使用 reduce() 与 forEach() 的非原始数组元素的总和

问题描述

我使用了以下代码,但无法解释结果为何不同:

let foo = [];
let bar = [...foo,{
  a: 1
},{
  a: 2
}];

let sum = bar.reduce((a,b) => a.a + b.a,0);
console.log(sum); // prints NaN

sum = 0;
bar.forEach((element) => {
  sum += element.a;
});
console.log(sum); // prints 3

解决方法

您的问题是 a 中的 (a,b) =>reduce 的累加器,它从 0(第二个参数)开始。这意味着它没有 a 属性,因此所有后续总和最终为 NaN,因为您将数字添加到 undefined(以及随后的 NaN)。要解决此问题,只需删除对 .a 的引用:

let foo = [];
let bar = [...foo,{
  a: 1
},{
  a: 2
}];

let sum = bar.reduce((a,b) => a + b.a,0);
console.log(sum); // prints 3

,

问题是 reduce() 链,您需要返回一个可以作为“下一个 a”的值。由于您在整数上引用 a.a,因此它进入 NaN 领域。

let sum = bar.reduce((a,b) => ({ a: a.a + b.a }),{ a: 0 });

一种可能更有效的方法是先对值进行归一化:

let sum = bar.map(a => a.a).reduce((a,b) => a + b,0);

现在它只是一个简单的数字数组。

,

reduce 函数的第一个参数是累加器。根据定义

累加器累加回调的返回值。它是先前在回调的最后一次调用中返回的累积值——或者是 initialValue,如果提供了它(见下文)。

如果您从 a.a 更改为 a 那么它应该可以工作。

let sum = bar.reduce((a,0);
,

您传递给reduce 函数的初始值是0,即。 a = 0 并尝试对返回 NaNundefined + 1 进行计算。您可以执行以下任一操作:

  1. 不传递初始值:

    bar.reduce((a,b) => a.a + b.a);

  2. 通过传递初始值,这里需要用到map:

    bar.map(a => a.a).reduce((a,0);

不过可以有更多的方法。您可以获得更多here