【问题标题】:How to merge hash of hash without replacing first hash如何在不替换第一个哈希的情况下合并哈希的哈希
【发布时间】:2016-12-14 17:43:34
【问题描述】:

考虑两个哈希:

     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,正如其他一些不起作用的答案所建议的那样。

【问题讨论】:

    标签: ruby-on-rails ruby hash


    【解决方案1】:

    Hash#merge 与块一起使用:

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 感谢您的回答,但我知道 deep_merge 在 rails 5 中已被弃用
      • 感谢您的信息,我不知道。 Rails 肯定是一个移动的目标!顺便说一句,接受的答案在一般情况下不起作用。例如,h1 = {a: {b: {c: 1} } }; h2 = {a: {b: {d: 2} } } 没有正确合并。
      猜你喜欢
      • 2014-03-30
      • 2013-07-21
      • 1970-01-01
      • 1970-01-01
      • 2016-03-30
      • 2019-09-08
      • 2017-12-18
      • 2011-05-27
      • 2012-08-17
      相关资源
      最近更新 更多