在哈希中合并值

时间:2012-10-07 18:48:00

标签: ruby hash merge inject

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

我一直在努力了解如何返回一个新的节点哈希,其中每个节点的:variables哈希与以下节点中的变量:变量来自: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没有按预期工作......

5 个答案:

答案 0 :(得分:1)

您想要Hash#merge

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

答案 1 :(得分:1)

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

答案 2 :(得分: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 ...如果你需要任何复杂的东西,这种基于散列的方法会变得非常笨重。< / p>

答案 3 :(得分: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}}}

答案 4 :(得分: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}}