a = [{"b"=>123,"c"=>456}, {"b"=>456,"c"=>555}]
b = [{"c"=>456,"d"=>789}, {"b"=>222,"c"=>444}]
def merge_hashes_with_equal_values(array_of_hashes, key)
array_of_hashes.sort { |a,b| a[key] <=> b[key] }.
chunk { |h| h[key] }.
each_with_object([]) { |h, result| result << h.last.inject(&:merge) }
end
p merge_hashes_with_equal_values(a + b, 'c')
# => [{"b"=>222, "c"=>444}, {"c"=>456, "d"=>789, "b"=>123}, {"b"=>456, "c"=>555}]
首先连接数组,然后将其传递给带有哈希键的方法以进行组合。对该数组进行排序,然后将要合并的散列放在另一个数组中,这使得合并更容易编程。在这里,我选择#chunk 来处理检测连续运行的具有相等键的哈希以进行合并,并选择#each_with_object 来编译最终数组。
由于此方法需要一个数组来处理,因此起始数组的长度不需要相等,并且这些数组的顺序无关紧要。缺点是要操作的键必须包含可排序的值(例如,没有 nil)。
这是解决该问题的另一种方法,该方法使用哈希来构建结果:
def merge_hashes_with_equal_values(array_of_hashes, key)
result = Hash.new { |h,k| h[k] = {} }
remainder = []
array_of_hashes.each_with_object(result) do |h, answer|
if h.has_key?(key)
answer[h.fetch(key)].merge!(h)
else
remainder << h
end
end.values + remainder
end