How to combine hashes if the specified key values ​​are the same in the array

I have an array of hashes like this:

[ {:foo=>2, :date=>Sat, 01 Sep 2014},
 {:foo2=>2, :date=>Sat, 02 Sep 2014},
 {:foo3=>3, :date=>Sat, 01 Sep 2014},
 {:foo4=>4, :date=>Sat, 03 Sep 2014},
  {:foo5=>5, :date=>Sat, 02 Sep 2014}]

And I want to combine hashes if they :datematch. What I expect from the array above:

[ {:foo=>2, :foo3=>3, :date=>Sat, 01 Sep 2014},
 {:foo2=>2, :foo5=>5 :date=>Sat, 02 Sep 2014},
 {:foo4=>4, :date=>Sat, 03 Sep 2014}]

How can i do this?

Perhaps I should review the data structure? For example, should a value be used dateas a hash key?

+4
source share
2 answers

Here you can do it in a line ( demo ):

hashes.group_by{|h| h[:date] }.map{|_, hs| hs.reduce(:merge)}

This code performs the following actions:

  • groups all hashes by value :date
  • for each group :date, accepts all hashes in it and combines them into one hash

EDIT: , tokland Cary Swoveland. !

+7

Hash # update (aka merge!), , , .

arr = [ {:foo=>2, :date=>'Sat, 01 Sep 2014'},
        {:foo2=>2, :date=>'Sat, 02 Sep 2014'},
        {:foo3=>3, :date=>'Sat, 01 Sep 2014'},
        {:foo4=>4, :date=>'Sat, 03 Sep 2014'},
        {:foo5=>5, :date=>'Sat, 02 Sep 2014'}]

arr.each_with_object({}) do |g,h|
  h.update({ g[:date]=>g }) { |_,o,n| o.merge(n) }
end.values
  #=> [{:foo=>2,  :date=>"Sat, 01 Sep 2014", :foo3=>3},
  #    {:foo2=>2, :date=>"Sat, 02 Sep 2014", :foo5=>5},
  #    {:foo4=>4, :date=>"Sat, 03 Sep 2014"}]

placeholder _ , , .

0

All Articles