Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby: How to group a Ruby array?

I have a Ruby array

> list = Request.find_all_by_artist("Metallica").map(&:song) => ["Nothing else Matters", "Enter sandman", "Enter Sandman", "Master of Puppets", "Master of Puppets", "Master of Puppets"] 

and I want a list with the counts like this:

{"Nothing Else Matters" => 1,  "Enter Sandman" => 2,  "Master of Puppets" => 3} 

So ideally I want a hash that will give me the count and notice how I have Enter Sandman and enter sandman so I need it case insensitive. I am pretty sure I can loop through it but is there a cleaner way?

like image 855
Matt Elhotiby Avatar asked Oct 07 '10 18:10

Matt Elhotiby


People also ask

How do I group an array in Ruby?

The group by creates a hash from the capitalize d version of an album name to an array containing all the strings in list that match it (e.g. "Enter sandman" => ["Enter Sandman", "Enter sandman"] ). The map then replaces each array with its length, so you get e.g. ["Enter sandman", 2] for "Enter sandman" .

How does group by work in Ruby?

The group_by() of enumerable is an inbuilt method in Ruby returns an hash where the groups are collectively kept as the result of the block after grouping them. In case no block is given, then an enumerator is returned. Parameters: The function takes an optional block according to which grouping is done.

How do you split an array in Ruby?

split is a String class method in Ruby which is used to split the given string into an array of substrings based on a pattern specified. Here the pattern can be a Regular Expression or a string. If pattern is a Regular Expression or a string, str is divided where the pattern matches.

How do you append to an array in Ruby?

Ruby has Array#unshift to prepend an element to the start of an array and Array#push to append an element to the end of an array. The names of these methods are not very intuitive. Active Support from Rails already has aliases for the unshift and push methods , namely prepend and append.


2 Answers

list.group_by(&:capitalize).map {|k,v| [k, v.length]} #=> [["Master of puppets", 3], ["Enter sandman", 2], ["Nothing else matters", 1]] 

The group by creates a hash from the capitalized version of an album name to an array containing all the strings in list that match it (e.g. "Enter sandman" => ["Enter Sandman", "Enter sandman"]). The map then replaces each array with its length, so you get e.g. ["Enter sandman", 2] for "Enter sandman".

If you need the result to be a hash, you can call to_h on the result or wrap a Hash[ ] around it.

like image 68
sepp2k Avatar answered Sep 22 '22 13:09

sepp2k


list.inject(Hash.new(0)){|h,k| k.downcase!; h[k.capitalize] += 1;h} 
like image 33
ghostdog74 Avatar answered Sep 21 '22 13:09

ghostdog74