如何在不替换第一个哈希的情况下合并哈希哈希

时间:2016-12-13 15:39:42

标签: ruby-on-rails ruby hash

考虑两个哈希:

     h1 =  {a: 1, b: 2, d: {g: 7, h: 6}}
     h2 =  {a: 1, b: 2, d: {m: 4, n: 5}}

我正在尝试将两个哈希合并为:

h1.merge(h2)

结果:{:a => 1,:b => 2,:d => {:m => 4,:n => 5}}

有人可以指导我获得像:

这样的哈希
{:a=>1, :b=>2, :d=>{:m=>4, :n=>5, :g=>7, :h=>6}} 

我曾尝试使用 deep_merge ,这是其他一些不起作用的答案。

2 个答案:

答案 0 :(得分:3)

Hash#merge与块一起使用:

h1.merge(h2) do |k, v1, v2|
  v1.is_a?(Hash) && v2.is_a?(Hash) ? v1.merge(v2) : v2
end

答案 1 :(得分:1)

deep_merge工作正常,但需要定义。

普通红宝石

class Hash
  def deep_merge(h2)
    merge(h2) { |_, v1, v2| v1.is_a?(Hash) && v2.is_a?(Hash) ? v1.deep_merge(v2) : v2 }
  end
end

h1 =  { a: 1, b: 2, d: { g: 7, h: 6 } }
h2 =  { a: 1, b: 2, d: { m: 4, n: 5 } }

h1.deep_merge(h2)
# => {:a=>1, :b=>2, :d=>{:g=>7, :h=>6, :m=>4, :n=>5}}

此方法定义具有递归的优点,并且可以使用任何深度的哈希(请参阅昨天的example)。

最后,如果您想要与示例中完全相同的输出,则需要h2.merge(h1)

h2.deep_merge(h1) #=> {:a=>1, :b=>2, :d=>{:g=>7, :h=>6, :m=>4, :n=>5}}
h1.deep_merge(h2) #=> {:a=>1, :b=>2, :d=>{:m=>4, :n=>5, :g=>7, :h=>6}}

Rails 3& 4

Hash#deep_merge附带Rails 3 & 4

如果您使用Rails,则在使用deep_merge

之前无需定义任何内容

如果您安装了Rails,并希望在纯Ruby脚本中使用deep_merge,则可以使用:

require 'active_support/core_ext/hash'
h1.deep_merge(h2)
#=> {:a=>1, :b=>2, :d=>{:g=>7, :h=>6, :m=>4, :n=>5}}