Rubyで入れ子のhashを初期化するときには、最初に階層を決めておかないと
undefined method `[]' for nil:NilClass (NoMethodError)
みたいなエラーになったりします。
なので、階層ごとの初期化の方法をまとめてみました。
1次元
# 初期化
hash = {}
hash["a"] = 1
p hash # => {"a"=>1}
2次元
# 初期化
hash = Hash.new { |h,k| h[k] = {} }
hash["a"]["b"] = 1
p hash # => {"a"=>{"b"=>1}}
ちなみに hash = Hash.new( {} )
という書き方は期待した動きになりません。
# 初期化
hash = Hash.new( {} )
hash["a"]["b"] = 1
p hash # => {}
p hash.default # => {"b"=>1}
この書き方だとHash#defaultに設定されてしまうからです。1
3次元以上
# 初期化
hash = Hash.new { |h,k| h[k] = Hash.new(&h.default_proc) }
Arrayとの組み合わせ
# 初期化
hash = Hash.new { |h, k| h[k] = [] }
hash["a"].push(1)
hash["a"].push(2)
p hash # => {"a"=>[1, 2]}
こちらも hash = Hash.new( [] )
だと期待した動きになりません。2
hashにhashを格納するパターン
初期化時に決めずに、hashにhashを入れてもいけます。
hash1 = {}
hash2 = { "b" => 1 }
hash1["a"] = hash2
p hash1 # => {"a"=>{"b"=>1}}