2009-10-01 8 views

Répondre

5

Pour atteindre le format désiré, vous pouvez ajouter un appel à la carte à votre solution:

array.inject({}) { |h,v| h[v] ||= 0; h[v] += 1; h }.map {|k, v| {k => v}} 

Bien qu'il soit encore en une ligne, il commence à se salir.

+0

sympa, c'est tout! Merci. –

+3

Vous pouvez le nettoyer un peu en utilisant un Hash avec une valeur par défaut: 'array.inject (Hash.new (0)) {| h, v | h [v] + = 1; h} .map {| k, v | {k => v}} ' – rampion

+0

Et pour le trier (comme dans l'exemple de question), ajoutez' .sort_by {| o | o.keys [0]} 'à lui. * Maintenant * c'est en désordre. :) –

5

super base, enfin comprendre injecter:

array.inject({}) { |h,v| h[v] ||= 0; h[v] += 1; h }

Pas tout à fait là, mais presque

+0

pourquoi demandez-vous si vous connaissez la réponse? –

+2

Ce n'est pas illégal de répondre à votre propre question. La FAQ de SO dit même que c'est correct, tant que c'est dans un format de question. – Twisol

+1

pour aider les autres à trouver de bonnes informations. Peu importe qui y répond. ne vous inquiétez pas, je n'ai pas envie d'écrire des questions sur des sujets pour lesquels j'ai des réponses :). –

5
array.inject(Hash.new(0)) {|h,v| h[v] += 1; h } 

Pas une énorme différence, mais je préfère être explicite avec ce que je fais. Dire Hash.new(0) REMPLACE {} et h[v] ||= 0

+0

il est là, parfait. merci Ryan. –

4

Nécessite 1.8.7

a = [1, 1, 1, 1, 2, 2, 3, 5, 5, 5, 8, 13, 21, 21, 21] 
h = {} 
a.group_by {|e| e}.each {|k,v| h[k] = v.length} 
p h # => {5=>3, 1=>4, 2=>2, 13=>1, 8=>1, 3=>1, 21=>3} 
Questions connexes