Reputation: 161
I have an array of hashes set up as below:
array = [
{"1" => 1, "2" => 2, "3" =>3},
{"1" => 1, "2" => 2, "3" =>3},
{"1" => 1, "2" => 2, "3" =>3}
]
I'm trying to find a way to average the values of all the hashes with key "1"
, for example.
Can someone help?
Upvotes: 3
Views: 158
Reputation: 2967
array_data = [
{"1" => 1, "2" => 2, "3" =>3},
{"1" => 1, "2" => 2, "3" =>3},
{"1" => 1, "2" => 2, "3" =>3}
]
class Hash
def get_first
self['1']
end
end
class Array
def avg
sum / size
end
end
avg = array_data.map(&:get_first).avg
Upvotes: 0
Reputation: 33491
Considering the Ruby version, yield_self (alias then) might work:
[{ "1" => 10, "2" => 2, "3" =>3 },
{ "1" => 43, "2" => 2, "3" =>3 },
{ "1" => 4, "2" => 2, "3" =>3 }].map { |hash| hash.fetch('1', 0) }.then { |arr| arr.sum.fdiv(arr.size) }
# 19.0
Where (10 + 43 + 4) / 3 = 19.0
, not your example, but not just 1 + 1 + 1.
Upvotes: 2
Reputation: 80105
Array has a sum
method nowadays, which takes a block. It basically sums whatever the block returns:
array = [{"1" => 0, "2" => 2, "3" =>3}, {"1" => 1, "2" => 4, "3" =>6}, {"1" => 2, "2" => 6, "3" =>9}]
array.sum{|h| h['1']}.fdiv(array.size)
Upvotes: 4
Reputation: 11203
Given the array (I changed the values for easy of debug):
array = [{"1" => 0, "2" => 2, "3" =>3}, {"1" => 1, "2" => 4, "3" =>6}, {"1" => 2, "2" => 6, "3" =>9}]
This code map each key to the average of values:
array.each_with_object(Hash.new{ |k,v| k[v] = [ ]}) { |h, hh| h.each { |k,v| hh[k] << v } }.transform_values { |k| k.sum.to_f/k.size }
#=> {"1"=>1.0, "2"=>4.0, "3"=>6.0}
Upvotes: 0
Reputation: 107142
I would do something like this:
array = [{"1" => 1, "2" => 2, "3" =>3},{"1" => 1, "2" => 2, "3" =>3},{"1" => 1, "2" => 2, "3" =>3}]
array.map { |hash| hash['1'] }.inject { |sum, el| sum + el }.to_f / array.size
#=> 1.0
array.map { |hash| hash['1'] }
extracts the values for all elements with the key '1'
([1,1,1]
) in this example. And .inject{ |sum, el| sum + el }.to_f / array.size
calculates the average.
Upvotes: 0