Menu
Coddy logo textTech

Hash.new とデフォルト値

CoddyのRubyジャーニー「ロジックとフロー」セクションの一部 — レッスン 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 以上のカテゴリのみを、合計の降順でソートして、1行に1つずつ出力してください:

<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腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

ロジックとフローのすべてのレッスン