简体   繁体   中英

How to calculate the average in JavaScript of the given properties in the array of objects

I have an array of objects. Each object contains a few properties and one of these properties is age.

var people = [
  {
    name: 'Anna',
    age: 22
  },
  {
    name: 'Tom',
    age: 34
  }, {
    name: 'John',
    age: 12
  },
]

I want to calculate the average for all the age properties in this array. I use this function:

let getAverage = arr => {
  let reducer = (total, currentValue) => total + currentValue;
  let sum = arr.reduce(reducer)
  return sum / arr.length;
}

It works fine for the simple array like [22, 34, 12] but it does not for the arrays of objects.

How to modify my getAverage function to make it works also with arrays of object?

Here is the snippet with my code: https://jsfiddle.net/marektchas/kc8Ls0f5/2/

You can use reduce() and add property age of each object in array to ac . Don't forget to pass 0 (initial value of ac ) as second argument otherwise it would return NaN

 var people = [ { name: 'Anna', age: 22 }, { name: 'Tom', age: 34 }, { name: 'John', age: 12 }, ] let avgs = people.reduce((ac,a) => a.age + ac,0)/people.length console.log(avgs) 

You don't need to modify getAverage - you can pre-process the array before handing it off, in which case getAverage will work exactly as needed:

 var people = [ { name: 'Anna', age: 22 }, { name: 'Tom', age: 34 }, { name: 'John', age: 12 }, ] let getAverage = arr => { let reducer = (total, currentValue) => total + currentValue; let sum = arr.reduce(reducer) return sum / arr.length; } let ages = people.map(person => person.age); console.log(getAverage(ages)); 

If you want to change getAverage , so it can handle any potential type of input, then you can add an optional argument that will perform value extraction, so you don't have to run a map on each array.

 var numbers = [ 1, 2, 3, 4, 5 ] var people = [ { name: 'Anna', age: 22 }, { name: 'Tom', age: 34 }, { name: 'John', age: 12 }, ] var moreComplexObjects = [ { a: { b: { c: 6 } } }, { a: { b: { c: 7 } } }, { a: { b: { c: 8 } } } ] //the default value of the second parameter is a function that returns the input let getAverage = (arr, valueExtractor = x => x) => { //extract the value of each element let reducer = (total, currentValue) => total + valueExtractor(currentValue); let sum = arr.reduce(reducer, 0) //make sure you add an initialiser return sum / arr.length; } const ageExtractor = person => person.age; const complexKeyExtractor = obj => obj.abc; console.log(getAverage(numbers)); console.log(getAverage(people, ageExtractor)); console.log(getAverage(moreComplexObjects, complexKeyExtractor)); 

A note for the above, if you don't supply a second parameter to Array#reduce , then the first time it runs total will be the first element of the array, however the second time and onwards, it will be the sum so far. It's not worth handling that case, so supplying an initial value solves it.

We can use Array.reduce to compute the sum, where acc is the accumulated sum and the individual objects are destructured to the age variable then calculate the average by dividing the sum with the array length:

 var people = [ { name: 'Anna', age: 22 }, { name: 'Tom', age: 34 }, { name: 'John', age: 12 }, ]; function getAvg(arr){ return (people.reduce((acc, {age}) => (acc + age), 0))/arr.length; } console.log(getAvg(people)); 

We can also map the function to the age property and calculate the sum by joining the array into a string and evaluating it inside the Function constructor:

 var people = [ { name: 'Anna', age: 22 }, { name: 'Tom', age: 34 }, { name: 'John', age: 12 }, ]; function getAvg(arr){ return (new Function(`return ${people.map(({age}) => age).join("+")}`)()) / arr.length; } console.log(getAvg(people)); 

You could supply a function for the wanted property and reduce with a start value.

 const getAverage = (array, fn = v => v) => { var reducer = fn => (total, item) => total + fn(item), sum = array.reduce(reducer(fn), 0); return sum / array.length; }; var people = [{ name: 'Anna', age: 22 }, { name: 'Tom', age: 34 }, { name: 'John', age: 12 }]; console.log(getAverage(people, o => o.age)); 

More Simplified code

just execute as getAverage(people.map(p=> p.age)); using your code

 var people = [ { name: 'Anna', age: 22 }, { name: 'Tom', age: 34 }, { name: 'John', age: 12 }, ]; let getAverage = arr => { let reducer = (total, currentValue) => total + currentValue; let sum = arr.reduce(reducer) return sum / arr.length; }; console.log(getAverage(people.map(p=> p.age))); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM