所以我试图创建一个树数据结构,可以通过嵌套哈希实例化。
我的代码如下,并且应该递归地从密钥中取出节点,并将子节点从它们的值中取出。
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]
看起来每个人都将嵌套的哈希变成一个数组,其中键是第一个元素,值是第二个元素。
答案 0 :(得分: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
将始终是一个双元素数组。由于语法上的技巧,如果有多个形式参数,Ruby将自动splat一个数组参数,所以你也可以写:
hashTree[node_name].each do |name, hash|
这不会导致错误。 (实际上你在逻辑中仍然存在无关的错误,因为你正在跳过一个级别。)
无错误版本:
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)
使用map
:
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