How to combine two hash arrays

I have two hash arrays:

a = [ { key: 1, value: "foo" }, { key: 2, value: "baz" } ] b = [ { key: 1, value: "bar" }, { key: 1000, value: "something" } ] 

I want to combine them into one hash array, so essentially a + b , except that I want the duplicate key in b overwrite those in a . In this case, both a and b contain key 1 , and I want the final result to have a pair of b values.

Here's the expected result:

 expected = [ { key: 1, value: "bar" }, { key: 2, value: "baz" }, { key: 1000, value: "something" } ] 

I got it to work, but I was wondering if there is a less bland way to do this:

 hash_result = {} a.each do |item| hash_result[item[:key]] = item[:value] end b.each do |item| hash_result[item[:key]] = item[:value] end result = [] hash_result.each do |k,v| result << {:key => k, :value => v} end puts result puts expected == result # prints true 
+5
source share
4 answers

uniq will work if you combine arrays in reverse order:

 (b + a).uniq { |h| h[:key] } #=> [ # {:key=>1, :value=>"bar"}, # {:key=>1000, :value=>"something"}, # {:key=>2, :value=>"baz"} # ] 

However, it does not preserve order.

+5
source
 [a, b].map { |arr| arr.group_by { |e| e[:key] } } .reduce(&:merge) .flat_map(&:last) 

Here we use hash[:key] as the key to building a new hash, and then merge them all overridden with the last value and return values .

+1
source

I would rebuild your data a bit, as hashes have redundant keys:

 thin_b = b.map { |h| [h[:key], h[:value]] }.to_h #=> {1=>"bar", 1000=>"something"} thin_a = b.map { |h| [h[:key], h[:value]] }.to_h #=> {1=>"bar", 1000=>"something"} 

Then you can only use Hash#merge :

 thin_a.merge(thin_b) #=> {1=>"bar", 2=>"baz", 1000=>"something"} 

But, if you want, you can get exactly the result, as indicated in the question:

 result.map { |k, v| { key: k, value: v } } #=> [{:key=>1, :value=>"bar"}, # {:key=>2, :value=>"baz"}, # {:key=>1000, :value=>"something"}] 
+1
source

using Enumerated # group_by and Enumerated # card

 (b+a).group_by { |e| e[:key] }.values.map {|arr| arr.first} 
0
source

Source: https://habr.com/ru/post/1267295/


All Articles