Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Join common keys in hash one-liner

I have this array of pairs:

[{"a"=>"1"}, {"b"=>"2"}, {"a"=>"3"}, {"b"=>"4"}, {"a"=>"5"}]

I would like a method to merge the keys in common with multiple values to:

[{"a"=>["1","3","5"]}, {"b"=>["2","4"]}]
like image 835
Ben Orozco Avatar asked Jun 08 '11 22:06

Ben Orozco


2 Answers

Improved following Marc-Andre's suggestion.

array = [{"a"=>"1"}, {"b"=>"2"}, {"a"=>"3"}, {"b"=>"4"}, {"a"=>"5"}]
array.group_by(&:keys).map{|k, v| {k.first => v.flat_map(&:values)}}

Or

array.group_by{|h| h.keys.first}.each_value{|a| a.map!{|h| h.values.first}}
like image 137
sawa Avatar answered Nov 03 '22 18:11

sawa


Haven't tried it yet, but something like that should also works

   a.each_with_object( Hash.new{ |h,k| h[k] = [] } ) do |x, hash|
      hash[x.keys.first] << x.values.first
   end

edit: For a one liner, and the same output :

[a.each_with_object( Hash.new{ |h,k| h[k] = [] } ) { |x, hash| hash[x.keys.first] << x.values.first }]
like image 39
christianblais Avatar answered Nov 03 '22 16:11

christianblais