合并哈希的最佳方法是什么?

时间:2017-06-30 15:56:28

标签: ruby

我有两个类似的哈希。第一个看起来像:

{'1'=>
   {'ab'=>{'a'=>1, 'b'=>4},
   {'bc'=>{'b'=>2, 'c'=>1},
   ...
}

第二个非常相似:

{'1'=>
   {'ab'=>{'v'=>1},
   {'bc'=>{'v'=>2},
   ...
}

我想合并这些:

{'1'=>
   {'ab'=>{'a'=>1, 'b'=>4, 'v'=>1},
   {'bc'=>{'b'=>2, 'c'=>1, 'v'=>2},
   ...
}

最好的方法是什么?

2 个答案:

答案 0 :(得分:3)

对于这些简单的案例:

h1.merge(h2) do |_, v1, v2|
  v1.merge(v2) { |_, v1, v2| v1.merge(v2) }
end
#⇒ {"1"=>{"ab"=>{"a"=>1, "b"=>4, "v"=>1},
#         "bc"=>{"b"=>2, "c"=>1, "v"=>2}}}

另请注意,您作为输入发布的内容不是有效的ruby对象。

答案 1 :(得分:1)

从ActiveSupport尝试Hash#deep_mergehttps://apidock.com/rails/Hash/deep_merge

如果您不想依赖于active_support gem或不愿意修补核心类,那么您只需从AS复制算法并适应您的需求。

# File activesupport/lib/active_support/core_ext/hash/deep_merge.rb, line 21
  def deep_merge!(other_hash, &block)
    other_hash.each_pair do |current_key, other_value|
      this_value = self[current_key]

      self[current_key] = if this_value.is_a?(Hash) && other_value.is_a?(Hash)
        this_value.deep_merge(other_value, &block)
      else
        if block_given? && key?(current_key)
          block.call(current_key, this_value, other_value)
        else
          other_value
        end
      end
    end

    self
  end

更新:

我不确定为什么答案被低估了。这里有deep_merge

[10] pry(main)> a = {'1'=>
[10] pry(main)*   {'ab'=>{'a'=>1, 'b'=>4},
[10] pry(main)*   'bc'=>{'b'=>2, 'c'=>1}}
[10] pry(main)* };
[11] pry(main)>
[12] pry(main)> b = {'1'=>
[12] pry(main)*   {'ab'=>{'v'=>1},
[12] pry(main)*   'bc'=>{'v'=>2}}
[12] pry(main)* };
[13] pry(main)>
[14] pry(main)> a.deep_merge(b)
=> {"1"=>{"ab"=>{"a"=>1, "b"=>4, "v"=>1}, "bc"=>{"b"=>2, "c"=>1, "v"=>2}}}
[15] pry(main)>

完全 OP需要什么。