Hash.new со значениями по умолчанию
Часть раздела Логика и управление потоком путешествия по Ruby на Coddy — урок 33 из 56.
По умолчанию поиск отсутствующего ключа в хеше возвращает nil:
scores = {}
puts scores["Alice"] # nilHash.new(default) меняет это. Каждый отсутствующий ключ возвращает значение, которое вы передали:
scores = Hash.new(0)
puts scores["Alice"] # 0Это самый чистый способ написать счетчик. Вам не нужно проверять if scores[name].nil? перед инкрементированием:
counts = Hash.new(0)
["a", "b", "a", "c", "a"].each do |letter|
counts[letter] += 1
end
puts counts.inspect # {"a"=>3, "b"=>1, "c"=>1}Важно: Hash.new(0) устанавливает значение по умолчанию равным 0, но не сохраняет ключ при чтении. Хеш остается пустым до тех пор, пока вы не выполните присваивание. Таким образом, как только вы напишете counts[letter] += 1, ключ будет добавлен с новым значением.
Задание
ЛегкоПрочитайте список записей category:amount, разделенных запятыми (например, food:12,gas:30,food:8,books:25,gas:15). Создайте хеш итоговых сумм по категориям, используя Hash.new(0), затем выведите только те категории, общая сумма которых составляет не менее 20, по одной на строку, отсортированных по сумме по убыванию:
<category>: <total>Для приведенного выше примера ввода вывод будет следующим:
gas: 45
books: 25
food: 20Если ни одна категория не достигает 20, ничего не выводите.
Шпаргалка
По умолчанию отсутствующие ключи хеша возвращают nil. Используйте Hash.new(default), чтобы вместо этого возвращать другое значение по умолчанию:
scores = Hash.new(0)
puts scores["Alice"] # 0Это делает счетчики чистыми — нет необходимости проверять на nil перед инкрементированием:
counts = Hash.new(0)
["a", "b", "a"].each do |letter|
counts[letter] += 1
end
# {"a"=>2, "b"=>1}Примечание: чтение отсутствующего ключа не сохраняет его. Ключ добавляется только после того, как вы присвоите значение (например, +=).
Попробуйте сами
entries = gets.chomp.split(",")
# TODO: totals = Hash.new(0); суммировать суммы по категориям;
# затем вывести категории с итогом >= 20, отсортированные по убыванию итога
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и управление потоком
1Строки в деталях
Обзор методов строкИнтерполяция строкИтерация по строкамSplit и JoinИтоги — String Weaver4Блоки, Proc и лямбды
Что такое блок?do..end против фигурных скобокКлючевое слово yieldПараметры блокаProc и лямбдыИтоги: пользовательский итератор7Хеши. Часть 2
Hash.new со значениями по умолчаниюИтерация по хешамВложенные хешиСлияние и преобразованиеИтоги — счетчик частоты10Проект — Учёт студентов
Обзор проектаДобавить студента2Диапазоны
Что такое диапазон?Методы диапазоновДиапазоны в Case / WhenПовторение — практика по диапазонам5Мощь Enumerable
Select и RejectЦепочки MapReduce / Injectcount, all?, any?, none?group_by и partitionsort_by, min_by, max_byИтоги — Data Pipeline8Продвинутые условные конструкции
Case с классами и RegexМножественные значения в whenТернарный операторОднострочные if / unlessПовторение: Классификатор оценок