2012-08-22 17 views
7

tengo este conjunto de hashes:Cómo encontrar y devolver un valor hash dentro de una gama de valores hash, dado varios otros valores en el hash

results = [ 
    {"day"=>"2012-08-15", "name"=>"John", "calls"=>"5"}, 
    {"day"=>"2012-08-15", "name"=>"Bill", "calls"=>"8"}, 
    {"day"=>"2012-08-16", "name"=>"Bill", "calls"=>"11"}, 
] 

¿Cómo puedo buscar en los resultados para encontrar el número de llamadas de Bill hecho el día 15?

Después de leer las respuestas a "Ruby easy search for key-value pair in an array of hashes", creo que podría implicar la ampliación de la declaración siguiente hallazgo:

results.find { |h| h['day'] == '2012-08-15' }['calls'] 

Respuesta

15

Estás en el ¡buen camino!

results.find {|i| i["day"] == "2012-08-15" and i["name"] == "Bill"}["calls"] 
# => "8" 
+0

¡He intentado con una coma allí antes, pero tu _y_ funciona perfectamente! Muchas gracias. – s2t2

+4

@ s2t2 también puede usar '&&' instad if 'y' – PriteshJ

0

Una aplicación realmente torpes;)

def get_calls(hash,name,date) 
hash.map{|result| result['calls'].to_i if result['day'] == date && result["name"] == name}.compact.reduce(:+) 
end 

date = "2012-08-15" 
name = "Bill" 

puts get_calls(results, name, date) 
=> 8 
+1

puede utilizar @ versión ARun32 si está seguro de que tiene sólo un registro por combinación – PriteshJ

+0

Tengo solo un registro por combo. Gracias. – s2t2

1
results.select { |h| h['day'] == '2012-08-15' && h['name'] == 'Bill' } 
    .reduce(0) { |res,h| res += h['calls'].to_i } #=> 8 
0

En realidad, "reducir" o "inyectar" es específicamente para esta operación exacta (Para reducir el contenido de un enumerable abajo en un solo valor:

results.reduce(0) do |count, value| 
    count + (value["name"]=="Bill" && value["day"] == "2012-08-15" ? value["calls"].to_i : 0) 
end 

Niza writeup aquí: "Understanding map and reduce"

0

otra forma posible, pero un poco peor, usando inyectar: ​​

results.inject(0) { |number_of_calls, arr_element| arr_element['day'] == '2012-08-15' ? number_of_calls += 1 : number_of_calls += 0 } 

Tenga en cuenta que usted tiene que fijar number_of_calls en cada iteración, de lo contrario no funcionará, por ejemplo, esto no funciona:

p results.inject(0) { |number_of_calls, arr_element| number_of_calls += 1 if arr_element['day'] == '2012-08-15'} 
Cuestiones relacionadas