56 votes

Grouper un tableau de rubis

J'ai un tableau de rubis

 > 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"]
 

et je veux une liste avec les comptes comme ceci:

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

Donc, idéalement, je veux un hachage qui me donnera le compte et remarque comment je sais entrer Sandman et entrer sandman, alors j’ai besoin que ce soit insensible à la casse ... Je suis à peu près sûr que je pourrai le parcourir mais ya-t-il un moyen plus propre?

99voto

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

Le groupe by crée un hachage de la version capitalize d du nom de l’album dans un tableau contenant toutes les chaînes de list qui lui correspondent (par exemple, "Enter sandman" => ["Enter Sandman", "Enter sandman"] ). Le map remplace alors chaque tableau par sa longueur, vous obtenez ainsi par exemple ["Enter sandman", 2] pour "Enter sandman" .

Si vous voulez que le résultat soit un hash, vous pouvez envelopper un Hash[ ] autour.

11voto

ghostdog74 Points 86060
list.inject(Hash.new(0)){|h,k| k.downcase!; h[k.capitalize] += 1;h}

9voto

glenn jackman Points 69748

Une autre prise:

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

Comme je l'ai dit, vous pourriez préférer titlecase

5voto

Harish Shetty Points 38877

Le regroupement et le tri d'un ensemble de données de taille inconnue dans Ruby doivent être un choix ultime. C’est une corvée qu'il vaut mieux laisser à DB. En règle générale, les problèmes comme le vôtre sont résolus à l'aide d'une combinaison de clauses COUNT , GROUP BY , HAVING et ORDER BY . Heureusement, rails fournit une méthode count pour de tels cas d'utilisation.

 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
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X