我有一个对象数组。每个对象都包含一些属性,其中一个属性是age。
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;
}
它对于像[22、34、12]这样的简单数组都可以正常工作,但不适用于对象数组。
如何修改我的getAverage函数以使其也可以用于对象数组?
答案 0 :(得分:4)
您可以使用reduce()
并将数组中每个对象的属性age
添加到ac
。不要忘记将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)
答案 1 :(得分:3)
您不需要修改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));
如果要更改getAverage
,以便它可以处理任何可能的输入类型,则可以添加一个可选参数来执行值提取,因此不必运行{{1} }。
map
上述注意事项,如果您没有为Array#reduce
提供第二个参数,那么它运行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.a.b.c;
console.log(getAverage(numbers));
console.log(getAverage(people, ageExtractor));
console.log(getAverage(moreComplexObjects, complexKeyExtractor));
的 first 时间将是数组,但是 second 时间及以后的时间将是到目前为止的总和。处理这种情况不值得,因此提供一个初始值即可解决问题。
答案 2 :(得分:2)
我们可以使用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));
我们还可以将函数映射到age
属性,并通过将数组连接到字符串并在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));
答案 3 :(得分:2)
您可以为所需属性提供一个函数,并以一个起始值进行归约。
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));
答案 4 :(得分:1)
更多简化代码
只需使用代码
以 getAverage(people.map(p => p.age)); 身份执行
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)));