2011-04-15 101 views
3

我想加入2个或更多散列。使用其他散列构造散列

h1 = { :es => { :hello => "You" } } 
h2 = { :es => { :bye => "Man" } } 

我该如何得到这个?

h1 + h2 = { :es => { :hello => "you", :bye => "Man" } } 

谢谢。

+1

你想合并递归吗?例如。如果你有:':{:es => {:abc => {:child_1 => 1}}}'和'{:es => {:abc => {:child_2 => 2}}}'?你需要'{:es => {:abc => {:child_1 => 1,:child_2 => 2}}}'? – Kelvin 2011-04-15 21:21:06

回答

4

你想要的是deep_merge方法。正是你想要的。

ruby-1.9.2-p136 :001 > {:es => {:hello => "You" } }.deep_merge({:es => {:bye => "Man"}}) 
=> {:es=>{:hello=>"You", :bye=>"Man"}} 

http://apidock.com/rails/ActiveSupport/CoreExtensions/Hash/DeepMerge/deep_merge

+1

请注意,您需要为此提供有效支持。 – 2011-04-15 21:31:17

+0

是的。我找到了相同的解决方案。我在rails中使用deep_merge。谢谢。 – 2011-04-17 19:11:40

5
irb(main):001:0> h1 = {:es => {:hello => "You"}} 
=> {:es=>{:hello=>"You"}} 
irb(main):002:0> h2 = {:es => {:bye => "Man"}} 
=> {:es=>{:bye=>"Man"}} 
irb(main):003:0> h1.each_key {|x| h1[x].merge! h2[x]} 
=> {:es=>{:bye=>"Man", :hello=>"You"}} 
0

到的ActiveSupport的deep_merge相似,但功能性的方法。以递归方式工作:

class Hash 
    def inner_merge(other_hash) 
    other_hash.inject(self) do |acc, (key, value)| 
     if (acc_value = acc[key]) && acc_value.is_a?(Hash) && value.is_a?(Hash) 
     acc.merge(key => acc_value.inner_merge(value)) 
     else 
     acc.merge(key => value) 
     end 
    end  
    end 
end 

h1.inner_merge(h2) #=> {:es=>{:hello=>"You", :bye=>"Man"}} 
0

如果您不使用ActiveSupport,则此Proc将执行深度合并。 1.8.7 & 1.9.2兼容。

dm = lambda {|l,r| l.merge(r) {|k,ov,nv| l[k] = ov.is_a?(Hash) ? dm[ov, nv || {}] : nv} } 
dm[h1,h2] 
# => {:es=>{:hello=>"You", :bye=>"Man"}}