Rubyでの多次元Hashの作成法
あるいは深さを指定したツリーの作成法。
なんかセオリーがあるのかなと思って探してみたけど、次元数が可変な作成方法は見つからなかった。
試行錯誤しながら作ってたらなんか結構短くなったので公開。
dimension = 3 nodes = [] nodes << {} # 末端Hash (dimension-1).times do node = nodes.shift nodes << Hash.new{ |hash, key| hash[key] = node.dup } end tree = nodes.shift
使用例
tree[:a][:a][:a] = :aaa p tree # {:a=>{:a=>{:a=>:aaa}}} tree[:a][:a][:b] = :aab p tree # {:a=>{:a=>{:b=>:aab, :a=>:aaa}}} tree[:a][:b][:a] = :aba p tree # {:a=>{:b=>{:a=>:aba}, :a=>{:b=>:aab, :a=>:aaa}}}
各ノードは単なるHashなので他のオブジェクトで上書き可能
tree[:b][:a] = :ba p tree # {:b=>{:a=>:ba}, :a=>{:b=>{:a=>:aba}, :a=>{:b=>:aab, :a=>:aaa}}}
だからってこんな代入すると無限ループになるよ
tree[:a][:b][:b] = tree[:b] tree[:b][:b][:b] = tree[:a] p tree # {:b=>{:b=>{:b=>{:b=>{:b=>{...}, :a=>:aba}, :a=>{:b=>:aab, :a=>:aaa}}}, :a=>:ba}, :a=>{:b=>{:b=>{:b=>{:b=>{...}}, :a=>:ba}, :a=>:aba}, :a=>{:b=>:aab, :a=>:aaa}}}