Home > OS >  Merge multiple array of hashes where a value matches in Ruby
Merge multiple array of hashes where a value matches in Ruby

Time:03-30

I have 3 arrays with multiple hashes that I am trying to convert into a single array of hashes where a key/value matches

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

to get

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

CodePudding user response:

I think this is what you need.

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

CodePudding user response:

This just looks cooler, and should still solve your case too:

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

Console:

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

CodePudding user response:

[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"}]
  •  Tags:  
  • ruby
  • Related