2012-09-27 16 views
12

Ho un array di hash in Ruby che assomiglia a questo:Conteggio valori hash in 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"} 
] 

Da questo array di hash Voglio creare un nuovo hash simile a questa:

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

C'è un modo semplice per farlo usando Ruby 1.9?

+3

questo hash è collisione chiavi. – Kyle

+6

Questo hash non sembra che tu lo voglia. Ci può essere solo una voce con una data chiave in un hash, quindi avrai solo una voce (penso sia garantita "" country "=>" Norvegia "'. Vorresti una risposta per un array? – Chowlett

+1

Accanto il problema con il tuo hash sorgente. Ti aspetti '" Regno Unito "=>" Regno Unito "' o '" Regno Unito "=> 2'? – knut

risposta

10

Che ne dici di questo?

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

Perfetto! - Sei un risparmiatore di vita. Ho passato anni a cercare di farlo funzionare !! Grazie! – 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

Cosa succede quando ci sono più di 9 istanze di un paese? :) –

+2

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

+1

Grazie, non me l'aspettavo. :) Avrei dovuto leggere il manuale prima di commentare. –