0
nodes = {
  :node1 => { 
    :inherits => nil, 
    :variables => { :foo => 1, :bar => 2 } 
  },
  :node2 => { 
    :inherits => :node1, 
    :variables => { :foo => 9, :baz => 4 } 
  }
}

我一直在尝试了解如何返回一个新的节点哈希,其中每个节点的 :variables 哈希与 :inheritance 中指定的节点的 :variables 合并。换句话说, node1 将保持原样,而 node2 以 :variabes => { :foo => 9, :bar => 2, :baz => 4 } 结束

我一直在浏览涉及 Enumerable#inject、Hash#merge 和块等的文档,并认为是时候寻求帮助了。

更新:

想我会提供更新。这段代码当然不是解决方案,但它可能正朝着正确的方向前进......

nodes = {
  :node1 => { :inherits => nil, :variables => { :foo => 1, :bar => 2 } },
  :node2 => { :inherits => :node1, :variables => { :foo => 9, :baz => 4 } }
}

new = nodes.inject({}) do |result, (k, v)|
  result.merge k => v.merge({ :variables => { :a => 6, :b => 7 } })
end

返回

{:node2=>{:inherits=>:node1, :variables=>{:a=>6, :b=>7}}, :node1=>{:inherits=>nil, :variables=>{:a=>6, :b=>7}}}

所以 v.merge 没有按预期工作......

4

5 回答 5

1

你想要Hash#merge

merged_variables = nodes[:node1][:variables].merge(nodes[:node2][:variables])
于 2012-10-07T18:49:46.957 回答
1
nodes[:node2][:variables].replace(
  nodes[:node1][:variables]
  .merge(nodes[:node2][:variables])
)
于 2012-10-07T18:52:57.830 回答
0
merged_nodes = {}

nodes.each do |name, node|
  merged_nodes[name] = node.dup
  merged_nodes[name][:variables] = if node[:inherits]
    nodes[node[:inherits]][:variables].merge node[:variables]
  else
    node[:variables].dup
  end
end

会给你

{
  :node1=>{:inherits=>nil, :variables=>{:foo=>1, :bar=>2}},
  :node2=>{:inherits=>:node1, :variables=>{:foo=>9, :bar=>2, :baz=>4}}
}

但它不会处理更深层次的嵌套,即如果:node3then 继承:node2......如果您需要任何如此复杂的东西,这种基于散列的方法将变得非常笨拙。

于 2012-10-07T19:53:41.770 回答
0

通过就地合并缩短一点:

nodes[:node2][:variables].merge!(nodes[:node1][:variables])

nodes #=> {:node1=>{:inherits=>nil, :variables=>{:foo=>1, :bar=>2}},
      #    :node2=>{:inherits=>:node1, :variables=>{:foo=>1, :baz=>4, :bar=>2}}}
于 2012-10-07T20:43:07.800 回答
0
new = {}
nodes.each do |e, v|
    v.each do |attribute, value|
        if attribute == :inherits
            new[e] = value.nil? ? v : nodes[value][:variables].merge( v[:variables] )
        end
    end
end

p new  #=> {:node1=>{:inherits=>nil, :variables=>{:foo=>1, :bar=>2}}, :node2=>{:foo=>9, :bar=>2, :baz=>4}}
于 2012-10-08T07:44:13.777 回答