2012-10-07 100 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}}