Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I calculate the average values in objects located in an array?

Tags:

ruby

average

Let's say I have an array like this:

[
  {
    "player_id"         => 1,
    "number_of_matches" => 2,
    "goals"             => 5
  },
  {
    "player_id"         => 2,
    "number_of_matches" => 4,
    "goals"             => 10
  }
]

I want to have the average goals per match among all the players, not the average for each individual player, but the total average.

I have in mind doing it with .each and storing each of the individual averages, and at the end add them all and divide by the number of players I have. However, I am looking for a Ruby/ one-liner way of doing this.

like image 806
Nobita Avatar asked Mar 09 '12 18:03

Nobita


People also ask

How do you find the average of an object?

The average is calculated by dividing the sum of all the values by the number of values.

How do you find the average of an array in C?

scanf("%f", &num[i]); And, the sum of each entered element is computed. sum += num[i]; Once the for loop is completed, the average is calculated and printed on the screen.

How do you find the average element of an array in Java?

Example 1 to calculate the average using arrays First, create an array with values and run. the for loop to find the sum of all the elements of the array. Finally, divide the sum with the length of the array to get the average of numbers.


2 Answers

As requested, a one-liner:

avg = xs.map { |x| x["goals"].to_f / x["number_of_matches"] }.reduce(:+) / xs.size

A more readable snippet:

goals, matches = xs.map { |x| [x["goals"], x["number_of_matches"]] }.transpose 
avg = goals.reduce(:+).to_f / matches.reduce(:+) if goals
like image 143
tokland Avatar answered Oct 21 '22 12:10

tokland


A slight modification to tokland's answer.

items.map{|e| e.values_at("goals", "number_of_matches")}.transpose.map{|e| e.inject(:+)}.instance_eval{|goals, matches| goals.to_f/matches}
like image 41
sawa Avatar answered Oct 21 '22 12:10

sawa