["Nothing else Matters", "En...">

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 need a list with the following graphs:

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

Ideally, I want the hash to give me an account and notice that I have Enter Sandman and Enter Sandman , so I need it to be case insensitive. I'm sure I can get through it, but is there a cleaner way?

+41
ruby ruby-on-rails
Oct 07 2018-10-18
source share
4 answers
 list.group_by(&:capitalize).map {|k,v| [k, v.length]} #=> [["Master of puppets", 3], ["Enter sandman", 2], ["Nothing else matters", 1]] 

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

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

+79
Oct 07 2018-10-10
source share
 list.inject(Hash.new(0)){|h,k| k.downcase!; h[k.capitalize] += 1;h} 
+11
Oct 08 2018-10-10T00:
source share

Another variant:

 h = Hash.new {|hash, key| hash[key] = 0} list.each {|song| h[song.downcase] += 1} ph # => {"nothing else matters"=>1, "enter sandman"=>2, "master of puppets"=>3} 

As I said, you may prefer titlecase

+7
Oct 07 '10 at 19:41
source share

Grouping and sorting an unknown size dataset in Ruby should be a last resort. This is the most difficult task left by the database. Typically, problems like yours are resolved using combinations of COUNT , GROUP BY , HAVING and ORDER BY . Fortunately, rails provide the COUNT method for such use cases.

 song_counts= Request.count( :select => "LOWER(song) AS song" :group => :song, :order=> :song, :conditions => {:artist => "Metallica"}) song_counts.each do |song, count| p "#{song.titleize} : #{count}" end 
+5
Oct 08 '10 at 6:27
source share



All Articles