Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to merge hashes if a specified key's values are same in a array

Tags:

arrays

ruby

hash

I have a 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 merge hashes if the :date are same. What I expect from the array above is:

[ {: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 it?

Maybe should I reconsider data structure itself? For example should I use date value as a key of hash?

like image 942
ironsand Avatar asked Dec 02 '14 12:12

ironsand


People also ask

How do you know if two hashes are equal?

Equality—Two hashes are equal if they each contain the same number of keys and if each key-value pair is equal to (according to Object#== ) the corresponding elements in the other hash. The orders of each hashes are not compared. Returns true if other is subset of hash.

How do you combine hash?

Hash#merge!() is a Hash class method which can add the content the given hash array to the other. Entries with duplicate keys are overwritten with the values from each other_hash successively if no block is given.


1 Answers

Here's how you could do it in a line (demo):

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

This code does the following:

  • groups all hashes by their :date value
  • for each :date group, takes all hashes in it and merges them all into one hash

EDIT: Applied modifications suggested by tokland and Cary Swoveland. Thanks!

like image 78
Cristian Lupascu Avatar answered Sep 28 '22 06:09

Cristian Lupascu