Reputation: 91
I am trying to find the averages of several hashes in an array that look like this:
[{"path"=>"/abcd.com", "time"=>0.503},
{"path"=>"/abcd.com", "time"=>0.765},
{"path"=>"/abcd.com", "time"=>0.553}]
The arrays are grouped by the path, and I want to find the average time it takes for this path to load.
Here is what I have so far:
averages = grouped_data.each do |array|
array.each do |hash|
hash["time"].reduce(:+) \ hash.length
end
end
It's not working I think because the times in the hashes are floats. So I tried a work around by adding a total and without using reduce
, but the total
returned 0
:
averages = grouped_data.each do |array|
total = 0
array.each do |hash|
hash["time"] += total \ hash.length
end
return total
end
I appreciate any help. Thank you!
Upvotes: 3
Views: 3305
Reputation: 9508
Made an assumption about your grouped_data
structure, please verify.
grouped_data = [
[
{"path"=>"/sale.html", "time"=>0.503},
{"path"=>"/sale.html", "time"=>0.765},
{"path"=>"/sale.html", "time"=>0.553}
],
[
{"path"=>"/sales.html", "time"=>1.0},
{"path"=>"/sales.html", "time"=>1.0},
{"path"=>"/sales.html", "time"=>4.0}
]
]
If you want the averages per path:
averages = grouped_data.map do |array|
array.inject(0) do |sum, hash|
sum + hash["time"]
end.fdiv(array.size)
end
#=> [0.6070000000000001, 2.0]
Or hashes with the path and average times:
avs = grouped_data.map { |array|
array.inject({}) { |sum, hash|
sum.merge(hash) { |k, o, n| k == 'time' ? o + n : o }
}.map { |k, v| [k, k == 'time' ? v.fdiv(array.size) : v] }.to_h
}
#=> [{ "path" => "/sale.html", "time" => 0.6070000000000001 },
# { "path" => "/sales.html", "time" => 2.0 }]
Upvotes: 1
Reputation: 1879
Try this:
array = [{"path"=>"/sale.html", "time"=>0.503}, {"path"=>"/sale.html", "time"=>0.765}, {"path"=>"/sale.html", "time"=>0.553}]
average = array.map { |x| x["time"] }.sum / array.size # 0.6070
You can also use sum
directly on array:
average = array.sum { |x| x["time"] } / array.size # 0.6070
Upvotes: 3