2011-10-24 20 views
8

Ho un hash in cui voglio usare i valori come chiavi in ​​un nuovo hash che contiene un conteggio di quante volte quell'elemento è apparso come un valore nell'hash originale.Ruby "count" metodo per hash

Quindi io uso:

hashA.keys.each do |i| 
    puts hashA[i] 
end 

uscita Esempio:

0 
1 
1 
2 
0 
1 
1 

E voglio il nuovo hash per essere il seguente:

{ 0 => 2, 1 => 4, 2 => 1 } 
+0

possibile duplicato di [Come contare gli elementi di stringa identici in un array di Ruby] (http://stackoverflow.com/questions/5128200/how-to-count-identical-string-elements-in-a-ruby -array). La struttura dei dati originale in questa domanda è un hash, ma stai buttando via le chiavi, quindi ti occuperai in modo efficace di 'hashA.values', che è un array. –

+0

@AndrewGrimm Meh; alla fine (e rapidamente), sì ... Ma quando si cerca con una mentalità "Ho una mappa" probabilmente non cercherete cose sugli array. –

risposta

17
counts = hashA.values.inject(Hash.new(0)) do |collection, value| 
    collection[value] +=1 
    collection 
end 
+5

+1 per nomi di variabili significative nel blocco; Ho dimenticato quando non conosci l'API, contano. –

7

TL; DR: hashA.values.inject(Hash.new(0)) { |m, n| m[n] += 1; m }

> hashA = { a: 0, b: 1, c: 1, d: 2, e: 0, f: 1, g: 1 } 
=> {:a=>0, :b=>1, :c=>1, :d=>2, :e=>0, :f=>1, :g=>1} 
> hashCounts = hashA.values.inject(Hash.new(0)) { |m, n| m[n] += 1; m } 
=> {0=>2, 1=>4, 2=>1}