2011-10-24 86 views
8

Tengo un hash en el que quiero utilizar los valores como claves en un nuevo hash que contiene un recuento de cuántas veces ese elemento apareció como un valor en el hash original.Ruby "count" método para hash

así que uso:

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

Ejemplo de salida:

0 
1 
1 
2 
0 
1 
1 

y quiero que el nuevo hash que es el siguiente:

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

posible duplicado de [Cómo contar elementos de cuerda idénticos en una matriz de Ruby] (http://stackoverflow.com/questions/5128200/how-to-count-identical-string-elements-in-a-ruby -formación). La estructura de datos original en esta pregunta es un hash, pero estás tirando las claves, por lo que efectivamente estás tratando con 'hashA.values', que es una matriz. –

+0

@AndrewGrimm Meh; eventualmente (y rápidamente), sí ... Pero cuando busca con una mentalidad de "Tengo un mapa", probablemente no buscará nada sobre las matrices. –

Respuesta

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

+1 para nombres de variables significativas en el bloque; Olvidé que cuando no conoces la API, importan. –

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}