具有reduce的对象数组中的字段总和返回NaN

时间:2018-03-30 13:07:43

标签: javascript reduce

我在javascript中看到了reduce函数的奇怪行为。

我有一个对象数组,如下所示:

[ { a:1 }, {a:2}, ... ]

我需要每个对象中a属性的总和,所以我写了这个:

const array = [{a:1}, {a:2}];
const reducer = (accumulator, currentValue) => accumulator.a + currentValue.a;
console.log(array.reduce(reducer));

这可以按预期工作。

如果我尝试使用包含单个对象的数组运行相同的代码,我会将该对象作为reduce调用的结果(这是预期的行为),所以我添加了一个默认值像这样减少函数调用:

const array = [{a:1}];
const reducer = (accumulator, currentValue) => accumulator.a + currentValue.a;
console.log(array.reduce(reducer, {a: 0}));

这也像魅力一样。

我希望能够使用包含多个元素的数组运行reduce调用的第二个版本,例如:

const array = [{a:1}, {a:2}];
const reducer = (accumulator, currentValue) => accumulator.a + currentValue.a;
console.log(array.reduce(reducer, {a: 0}));

但这会返回NaN,我不明白为什么。 有人可以解释一下吗?

3 个答案:

答案 0 :(得分:1)

使用Array.reduce()时,如果未说明初始值,则数组的第1项将成为初始值。由于您需要一个数字而不是一个对象作为结果,因此初始化为0.由于累加器现在是一个数字而不是对象,因此在函数体中使用accumulator而不是accumulator.a:< / p>

const array = [{a:1}, {a:2}, {a:3}];
const reducer = (accumulator, currentValue) => accumulator + currentValue.a;
console.log(array.reduce(reducer, 0));

你也可以检查累加器是否是一个对象,然后尝试访问它的属性,但我发现它比简单地说明一个初始值更令人困惑:

const array = [{a:1}, {a:2}, {a:3}];
const reducer = (accumulator, currentValue) => (typeof accumulator === 'object' ? accumulator.a : accumulator) + currentValue.a;
console.log(array.reduce(reducer));

答案 1 :(得分:1)

reducer是对象时,accumulator.a + currentValue.a会返回数值accumulator之和)。

accumulator初始化为0或返回accumulator本身,将其设为

const reducer = (accumulator, currentValue) => (accumulator.a += currentValue.a, accumulator);

<强>演示

const array = [{
  a: 1
}, {
  a: 2
}];
const reducer = (accumulator, currentValue) => (accumulator.a += currentValue.a, accumulator);
console.log(array.reduce(reducer, {
  a: 0
}));

注意

  • 此缩减器将返回{"a":3},但如果您只想要 sum 值,请打印其属性a

console.log(array.reduce(reducer, {
  a: 0
}).a);

答案 2 :(得分:0)

您需要将缩减器功能更改为

const reducer = (accumulator, currentValue) => ({ a: accumulator.a + currentValue.a });

您的原始代码无效,因为您返回的是Number,而不是您正在访问其属性的对象。