[英]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. 每个对象包含一些属性,其中一个属性是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. 它适用于像[22,34,12]这样的简单数组,但不适用于对象数组。
How to modify my getAverage function to make it works also with arrays of object? 如何修改我的getAverage函数,使其也可以与对象数组一起使用?
Here is the snippet with my code: https://jsfiddle.net/marektchas/kc8Ls0f5/2/ 以下是我的代码片段: https : //jsfiddle.net/marektchas/kc8Ls0f5/2/
You can use reduce()
and add property age
of each object in array to ac
. 您可以使用reduce()
并将数组中每个对象的属性age
添加到ac
。 Don't forget to pass 0
(initial value of ac
) as second argument otherwise it would return NaN
不要忘记传递0
( ac
初始值)作为第二个参数,否则它将返回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: 您不需要修改getAverage
- 您可以在将其关闭之前对数组进行预处理,在这种情况下, getAverage
将完全按照需要工作:
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. 如果要更改getAverage
,那么它可以处理任何可能的输入类型,那么您可以添加一个可执行值提取的可选参数,因此您不必在每个数组上运行map
。
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. 对于上面的注释,如果你没有为Array#reduce
提供第二个参数,那么它第一次运行total
将是数组的第一个元素,但是第二次及以后,它将是到目前为止的总和。 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: 我们可以使用Array.reduce
来计算总和,其中acc
是累积的总和,并且各个对象被解构为age
变量,然后通过将总和除以数组长度来计算平均值:
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: 我们还可以将函数映射到age
属性,并通过将数组连接到字符串并在Function
构造Function
对其进行求值来计算总和:
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)); 只需执行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)));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.