2016-10-24 17 views
0

私は、ネストされたハッシュによってインスタンス化することができるツリーデータ構造を作成しようとしています。Rubyは私のハッシュを配列に変換しますか?

私のコードは以下の通りであり、ノードをキーから再帰的に抜き出し、その値から子を抜き出すだけです。

class Tree 
    attr_accessor :children, :node_name 
    #def initialize(name, children=[]) 
    # @children = children 
    # @node_name = name 
    # end 
    def initialize(hashTree) 
     @node_name = hashTree.keys[0] 
     @children = [] 
     p node_name 
     hashTree[node_name].each do |hash| 
      children << Tree.new(hash) 
     end 
    end 
    #... 
end 

p = {'grandpa' => { 'dad' => {'child 1' => {}, 'child2' => {} }, 'uncle' => {'child 3' => {}, 'child 4' => {} } } } 
p p 
p Tree.new(p) 

私はそのコードを実行しようとすると、私は、次を得る:

{"grandpa"=>{"dad"=>{"child 1"=>{}, "child2"=>{}}, "uncle"=>{"child 3"=>{}, "child 4"=>{}}}} 
"grandpa" 
/Users/Matt/sw/sevenLang/week1/hw-tree.rb:8:in `initialize': undefined method `keys' for ["dad", {"child 1"=>{}, "child2"=>{}}]:Array (NoMethodError) 
    from /Users/Matt/sw/sevenLang/week1/hw-tree.rb:12:in `new' 
    from /Users/Matt/sw/sevenLang/week1/hw-tree.rb:12:in `block in initialize' 
    from /Users/Matt/sw/sevenLang/week1/hw-tree.rb:11:in `each' 
    from /Users/Matt/sw/sevenLang/week1/hw-tree.rb:11:in `initialize' 
    from /Users/Matt/sw/sevenLang/week1/hw-tree.rb:26:in `new' 
    from /Users/Matt/sw/sevenLang/week1/hw-tree.rb:26:in `<main>' 
[Finished in 0.1s with exit code 1] 

各キーが最初の要素である配列、および値にネストされたハッシュを回しているように見えます2番目の要素です。

+0

'hashTree'はハッシュですので、' hashTree.each do | hash | 'の' hash'もハッシュ – Jones

答えて

2

hashTree[node_name]p["grandpa"]であり、ハッシュある:キーと値:

{"dad"=>{"child 1"=>{}, "child2"=>{}}, "uncle"=>{"child 3"=>{}, "child 4"=>{}}} 

Hash#eachは、二つの要素の配列をもたらします。あなたは

hashTree[node_name].each do |hash| 

hashTree[node_name]はハッシュで書くのであれば、hashは常に2つの要素の配列になります。複数の仮パラメータがある場合にも書くことができますので、その文法でトリックに、Rubyは、配列引数を自動スプラットます:これはエラーにはなりません

hashTree[node_name].each do |name, hash| 

。 (あなたはレベルをスキップしているとしてあなたは実際にはまだ、ロジックで無関係なエラーを持っています。)

エラーのないバージョン:これはmapを使用することによって短縮することができ

class Tree 
    attr_accessor :children, :node_name 
    def initialize(name, hashTree) 
     @node_name = name 
     @children = [] 
     hashTree.each do |child_name, hash| 
      children << Tree.new(child_name, hash) 
     end 
    end 
end 

p = {'grandpa' => { 'dad' => {'child 1' => {}, 'child2' => {} }, 'uncle' => {'child 3' => {}, 'child 4' => {} } } } 
p Tree.new("Family", p) 

class Tree 
    attr_accessor :children, :node_name 
    def initialize(name, hashTree) 
     @node_name = name 
     @children = hashTree.map do |child_name, hash| 
      Tree.new(child_name, hash) 
     end 
    end 
end 
+0

ハットであることを願っています。 'children'はおそらく' @ children'でなければなりません。また、 'each'ブロックの' name'はおそらくあまりあいまいにならないように変更するべきです。 – Makoto

+0

@Makoto:それは文体の違いです。 'children'と' @ children'の両方は 'attr_accessor'(OPのコードの' node_name'と '@ node_nameと同じです)のために、初期化の後に同じことを行います。 – Amadan

+0

助けてくれてありがとう。私は提供されたハッシュがルートノードであるキーと単一のキー=>値のペアになると仮定しています。したがって、名前パラメータを追加する必要はありません。代わりに私はしました: 'hashTree [node_name] .each do | name、hash | ' ' \t \t \t子供<< Tree.new({名=>ハッシュ}) ' ' \t \t end' 書式を許してください。 – Jones

関連する問題