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.