2012-10-07 99 views
0
nodes = { 
    :node1 => { 
    :inherits => nil, 
    :variables => { :foo => 1, :bar => 2 } 
    }, 
    :node2 => { 
    :inherits => :node1, 
    :variables => { :foo => 9, :baz => 4 } 
    } 
} 

我一直在试图理解如何返回一个新的节点哈希,其中每个节点的变量哈希都与:inheritance中指定的节点中的变量合并在一起。换句话说,node1会保持原样,而node2最后会以:variabes => {:foo => 9,:bar => 2,:baz => 4}在哈希中合并值

我一直在游泳文档涉及Enumerable#inject,Hash#与块合并,等等,现在是时候请求帮助了。

更新:

我想提供一个更新。此代码是肯定不是解决办法,但它可能会在正确的方向上走向...

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是不工作...

回答

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}} 
} 

,但它不会处理更深嵌套也就是说,如果:node3然后继承:node2 ...如果您需要任何东西一样复杂的是,这种基于散列的方法是会得到很笨重。

+0

这似乎很好地工作。谢谢。 – user1727142

+0

继续深入研究并提出以下建议: 'new = nodes.inject({})do | result,(name,node)| vars = node [:inherits] .nil? ?节点[:variables]:节点[node [:inherits]] [:variables] result.merge name => node.merge(:variables => node [:variables] .merge(vars)) end' – user1727142

1

你想Hash#merge

merged_variables = nodes[:node1][:variables].merge(nodes[:node2][:variables]) 
+0

不会产生具有一个节点:富= 1? – Dmitri

+0

不,它不会:'{:foo => 9,:bar => 2,:baz => 4}' – meagar

+0

谢谢。这可能有点太具体,因为我试图返回一个新的节点哈希与每个节点的:根据需要合并的变量(根据继承)。我会更新我的原始问题以反映这一点。 – user1727142

1
nodes[:node2][:variables].replace(
    nodes[:node1][:variables] 
    .merge(nodes[:node2][:variables]) 
) 
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}}} 
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}}