我有两个类似的哈希。第一个看起来像:
{'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},
...
}
最好的方法是什么?
答案 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_merge
。 https://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需要什么。