我在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
,我不明白为什么。
有人可以解释一下吗?
答案 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
,而不是您正在访问其属性的对象。