合并多个哈希数组,其中一个值在 Ruby 中匹配

Merge multiple array of hashes where a value matches in Ruby

我有 3 个包含多个哈希的数组,我正试图将它们转换成单个哈希数组,其中 key/value 匹配

a = [{"name"=>"aaa", "a"=>"1", "b"=>"2"}, {"name"=>"bbb", "a"=>"1", "b"=>"2"}]
b = [{"name"=>"aaa", "c"=>"1", "d"=>"2"}, {"name"=>"bbb", "c"=>"1", "d"=>"2"}]
c = [{"name"=>"aaa", "e"=>"1", "f"=>"2"}, {"name"=>"bbb", "e"=>"1", "f"=>"2"}]

获得

combined = [{"name"=>"aaa", "a"=>"1", "b"=>"2", "c"=>"1", "d"=>"2", "e"=>"1", "f"=>"2"}, {"name"=>"bbb", "a"=>"1", "b"=>"2", "c"=>"1", "d"=>"2", "e"=>"1", "f"=>"2"}]

我想这就是你需要的。

hashes = [a, b, c]
result = hashes.inject([]) do |result, hash_array|
  hash_array.each do |hash|
    index = result.find_index{|item| item["name"] == hash["name"]}
    if index
      result[index] = result[index].merge(hash)
    else
      result << hash
    end
  end
  result
end

这看起来更酷,应该也能解决你的问题:

a.zip(b,c).map{|vertical_array| e.inject({}) {|result, k| result.merge(k)} }

控制台:

2.5.1 :016 > a.zip(b,c).map{|e|e.inject({}){|result, k| result.merge(k)} }
 => [{"name"=>"aaa", "a"=>"1", "b"=>"2", "c"=>"1", "d"=>"2", "e"=>"1", "f"=>"2"}, {"name"=>"bbb", "a"=>"1", "b"=>"2", "c"=>"1", "d"=>"2", "e"=>"1", "f"=>"2"}] 
[a,b,c].transpose
       .map { |arr| arr.reduce(&:merge) }
  #=> [{"name"=>"aaa", "a"=>"1", "b"=>"2", "c"=>"1", "d"=>"2", "e"=>"1", "f"=>"2"},
       {"name"=>"bbb", "a"=>"1", "b"=>"2", "c"=>"1", "d"=>"2", "e"=>"1", "f"=>"2"}]

如果不能保证 abc 的元素顺序,可以写成

[a,b,c].map { |arr| arr.sort_by { |h| h["name"] } }
       .transpose
       .map { |arr| arr.reduce(&:merge) }

(a+b+c).each_with_object({}) do |g,h|
  h.update(g["name"]=>g) { |_,o,n| o.merge(n) }
end.values

后者使用的形式Hash#update (aka merge!) that employs a block ({ |_,o,n| o.merge(n) }) to determine the values of keys that are present in both hashes being merged. Note that here the receiver of Hash#values

(a+b+c).each_with_object({}) do |g,h|
  h.update(g["name"]=>g) { |_,o,n| o.merge(n) }
end
  #=> {"aaa"=>{"name"=>"aaa", "a"=>"1", "b"=>"2", "c"=>"1",
  #            "d"=>"2", "e"=>"1", "f"=>"2"},
  #    "bbb"=>{"name"=>"bbb", "a"=>"1", "b"=>"2", "c"=>"1",
  #            "d"=>"2", "e"=>"1", "f"=>"2"}]

此计算还允许数据内容更加多样化。假设,例如:

a = [{"name"=>"aaa", "a"=>"1", "b"=>"2"}, {"name"=>"bbb", "a"=>"1", "b"=>"2"}]
b = [{"name"=>"bbb", "c"=>"1", "d"=>"2"}, {"name"=>"ccc", "c"=>"1", "d"=>"2"}]
c = [{"name"=>"ccc", "e"=>"1", "f"=>"2"}, {"name"=>"aaa", "e"=>"1", "f"=>"2"}]

然后

(a+b+c).each_with_object({}) do |g,h|
  h.update(g["name"]=>g) { |_,o,n| o.merge(n) }
end
  #=> {"aaa"=>{"name"=>"aaa", "a"=>"1", "b"=>"2", "e"=>"1", "f"=>"2"},
  #    "bbb"=>{"name"=>"bbb", "a"=>"1", "b"=>"2", "c"=>"1", "d"=>"2"},
  #    "ccc"=>{"name"=>"bbb", "c"=>"1", "d"=>"2", "e"=>"1", "f"=>"2"}]