2012-09-27 35 views
12

que tienen una serie de hash en Ruby que tiene este aspecto:Counting valores hash en Ruby

domains = [ 
    { "country" => "Germany"}, 
    {"country" => "United Kingdom"}, 
    {"country" => "Hungary"}, 
    {"country" => "United States"}, 
    {"country" => "France"}, 
    {"country" => "Germany"}, 
    {"country" => "Slovakia"}, 
    {"country" => "Hungary"}, 
    {"country" => "United States"}, 
    {"country" => "Norway"}, 
    {"country" => "Germany"}, 
    {"country" => "United Kingdom"}, 
    {"country" => "Hungary"}, 
    {"country" => "United States"}, 
    {"country" => "Norway"} 
] 

A partir de este conjunto de hashes quiero crear un nuevo hash de la apariencia algo como esto:

counted = { 
    "Germany" => "3", 
    "United Kingdom" => "United Kingdom", 
    "Hungary" => "3", 
    "United States" => "4", 
    "France" => "1" 
} 

¿Hay una manera fácil de hacerlo usando Ruby 1.9?

+3

este hash ha de chocar llaves. – Kyle

+6

Ese hash no se verá como lo quieres. Solo puede haber una entrada con una clave determinada en hash, por lo que solo tendrá una entrada (creo que se garantiza que es '" country "=>" Norway "'. ¿Desea una respuesta para una matriz? – Chowlett

+1

Beside el problema con el hash fuente. ¿Esperas '" United Kingdom "=>" United Kingdom "' or '" United Kingdom "=> 2'? – knut

Respuesta

10

¿Qué tal esto?

counted = Hash.new(0) 
domains.each { |h| counted[h["country"]] += 1 } 
counted = Hash[counted.map {|k,v| [k,v.to_s] }] 
+1

¡Perfecto! - Eres un salvavidas. Pasé años tratando de hacer que esto funcione! ¡Gracias! – user1513388

5
domains.each_with_object(Hash.new{|h,k|h[k]='0'}) do |h,res| 
    res[h['country']].succ! 
end 
=> {"Germany"=>"3", 
"United Kingdom"=>"2", 
"Hungary"=>"3", 
"United States"=>"3", 
"France"=>"1", 
"Slovakia"=>"1", 
"Norway"=>"2"} 
+0

¿Qué sucede cuando hay más de 9 instancias de un país? :) –

+2

'9'.sucC# =>' 10 ' – megas

+1

Gracias, no esperaba eso. :) Debería haber leído el manual antes de comentar. –