How to find and return a hash value in a hash array, given several other values ββin the hash
I have this hash array:
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"}, ] How can I find the results to find out how many calls were made on the 15th?
After reading the answers in Ruby, simply looking for a key-value pair in a hash array, "I think this may include an extension of the following find statement:
results.find { |h| h['day'] == '2012-08-15' }['calls'] You are on the right track!
results.find {|i| i["day"] == "2012-08-15" and i["name"] == "Bill"}["calls"] # => "8" results.select { |h| h['day'] == '2012-08-15' && h['name'] == 'Bill' } .reduce(0) { |res,h| res += h['calls'].to_i } #=> 8 A Really awkward implementation;)
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 In fact, βreduceβ or βenterβ specifically for this exact operation (To reduce the contents of an enumeration down to one value:
results.reduce(0) do |count, value| count + ( value["name"]=="Bill" && value["day"] == "2012-08-15" ? value["calls"].to_i : 0) end Good entry here: " Understanding the map and abbreviation "
Or another possible way, but a little worse using injection:
results.inject(0) { |number_of_calls, arr_element| arr_element['day'] == '2012-08-15' ? number_of_calls += 1 : number_of_calls += 0 } Please note that you must set number_of_calls at each iteration, otherwise this will not work, for example, this DOES NOT work:
p results.inject(0) { |number_of_calls, arr_element| number_of_calls += 1 if arr_element['day'] == '2012-08-15'}