Reorganizing a Ruby Array into a Hash

I have an array of Products , each of which has a name and a category. I would like to create a hash in which each key is a category line, and each element is a product of this category, akin to the following:

 { "Apple" => [ <Golden Delicious>, <Granny Smith> ], ... "Banana" => ... 

Is it possible?

+4
source share
4 answers

In 1.8.7+ or with active_support (or faces, I think), you can use group_by:

 products.group_by {|prod| prod.category} 
+8
source
 h = Hash.new {|h, k| h[k] = []} products.each {|p| h[p.category] << p} 
+3
source

The oneliner

 arr = [["apple", "granny"],["apple", "smith"], ["banana", "chiq"]] h = arr.inject(Hash.new {|h,k| h[k]=[]}) {|ha,(cat,name)| ha[cat] << name; ha} 

:-)

But I agree, #group_by is much more elegant.

+1
source
 # a for all # p for product new_array = products.inject({}) {|a,p| a[p.category.name] ||= []; a[p.category.name] << p} 
0
source

All Articles