如何在JavaScript中计算对象数组中给定属性的平均值

时间:2019-03-27 11:19:10

标签: javascript arrays javascript-objects

我有一个对象数组。每个对象都包含一些属性,其中一个属性是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函数以使其也可以用于对象数组?

以下是我的代码段: https://jsfiddle.net/marektchas/kc8Ls0f5/2/

5 个答案:

答案 0 :(得分:4)

您可以使用reduce()并将数组中每个对象的属性age添加到ac。不要忘记将0ac的初始值)作为第二个参数,否则它将返回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)));