Menu
Coddy logo textTech

Hash.new со значениями по умолчанию

Часть раздела Логика и управление потоком путешествия по Ruby на Coddy — урок 33 из 56.

По умолчанию поиск отсутствующего ключа в хеше возвращает nil:

scores = {}
puts scores["Alice"]   # nil

Hash.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, ключ будет добавлен с новым значением.

challenge icon

Задание

Легко

Прочитайте список записей 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, отсортированные по убыванию итога
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Логика и управление потоком