とあるハッシュオブジェクトがあって、存在しないキーで値を取得しようとするとnilが返る。
例えば以下のhashには:cというキーは存在しないため、hash[:c]はnilが返る。
1 2 3 4 5 6 7 8 |
irb(main):006:0* hash = {a: 1, b:2} => {:a=>1, :b=>2} irb(main):007:0> hash[:a] => 1 irb(main):008:0> hash[:b] => 2 irb(main):009:0> hash[:c] => nil |
ときとしてこの挙動(存在しないキーを指定して場合、nilが返る)を変更したいことがある。
例えば、以下のように、arrayオブジェクトを与えると、要素をkey、同一要素の数をvalueにもつハッシュを返す処理を作成したとする。
1 2 3 4 5 6 7 8 |
irb(main):024:0> array = ["a", "b", "c", "d", "b"] => ["a", "b", "c", "d", "b"] irb(main):025:0> array.reduce({}) do |hash, element| irb(main):026:1* hash[element] ||= 0 irb(main):027:1> hash[element] += 1 irb(main):028:1> hash irb(main):029:1> end => {"a"=>1, "b"=>2, "c"=>1, "d"=>1} |
ハッシュの存在しないkeyを指定した時のデフォルト値はnilなので、わざわざhash[element] ||= 0をしている。
このケースでは存在しないキーを指定して場合、0を返してほしい。
Hash#newは引数としてデフォルト値を指定でき、存在しないキーを指定して場合の返りの値を設定できる。
Hash.new(0)とすると、存在しないキーにアクセスした場合、0が返る。
これを使うと、上記は↓のように書き換えることができる。
1 2 3 4 5 |
irb(main):033:0* array.reduce(Hash.new(0)) do |hash, element| irb(main):034:1* hash[element] += 1 irb(main):035:1> hash irb(main):036:1> end => {"a"=>1, "b"=>2, "c"=>1, "d"=>1} |
まとめ
・ハッシュに対して存在しないkeyを指定した場合、デフォルトではnilが返る
・状況によってはデフォルト値を変更してハッシュを利用したほうが良い場合がある
コメント
記事ありがとうございます!
一つ質問なのですが、ハッシュにデフォルト値を設定する場合って
どんなときなのでしょうか?