假设我想对arr中的每个元素求和。
arr = [ { x: 1 }, { x: 2 }, { x: 4 } ];
arr.reduce(function(a, b){ return a.x + b.x; }); // => NaN
我有理由相信a。x在某些时候是没有定义的。
以下工作正常
arr = [ 1, 2, 4 ];
arr.reduce(function(a, b){ return a + b; }); // => 7
第一个例子中我做错了什么?
假设我想对arr中的每个元素求和。
arr = [ { x: 1 }, { x: 2 }, { x: 4 } ];
arr.reduce(function(a, b){ return a.x + b.x; }); // => NaN
我有理由相信a。x在某些时候是没有定义的。
以下工作正常
arr = [ 1, 2, 4 ];
arr.reduce(function(a, b){ return a + b; }); // => 7
第一个例子中我做错了什么?
当前回答
其他人已经回答了这个问题,但我认为我应该提出另一种方法。你可以结合一个映射(从a.x到x)和reduce(把x相加),而不是直接对a.x求和:
arr = [{x:1},{x:2},{x:4}]
arr.map(function(a) {return a.x;})
.reduce(function(a,b) {return a + b;});
不可否认,它可能会稍微慢一些,但我认为值得把它作为一个选项提出来。
其他回答
对于第一次迭代,'a'将是数组中的第一个对象,因此a.x + b.x将返回1+2,即3。
在下一次迭代中返回的3被赋值给a,所以a是一个数字n调用a。x会得到NaN。
简单的解决方法是先将数字映射到数组中,然后将其缩减如下:
arr.map(a=>a.x).reduce(function(a,b){return a+b})
这里arr.map(a=>a.x)将提供一个数字数组[1,2,4],现在使用.reduce(function(a,b){return a+b})将简单地添加这些数字,没有任何麻烦
另一个简单的解决方案是通过将0赋值给a来提供一个初始和为零,如下所示:
arr.reduce(function(a,b){return a + b.x},0)
在第一步中,它会工作得很好,因为a的值将是1,b的值将是2,但由于2+1将返回,在下一步中,b的值将是第一步的返回值,即3,因此b.x将是未定义的…而undefined + anyNumber将是NaN,这就是为什么你会得到这个结果。
相反,你可以尝试给初始值为零,即
arr.reduce(function(a,b){return a + b.x},0);
如果你有一个包含大量数据的复杂对象,比如一个对象数组,你可以采取一步一步的方法来解决这个问题。
如:
const myArray = [{ id: 1, value: 10}, { id: 2, value: 20}];
首先,你应该将你的数组映射到一个你感兴趣的新数组,在这个例子中它可能是一个新的值数组。
const values = myArray.map(obj => obj.value);
这个回调函数将返回一个只包含原始数组中的值的新数组,并将其存储在values const中。现在你的values const是一个这样的数组:
values = [10, 20];
现在你已经准备好执行reduce了:
const sum = values.reduce((accumulator, currentValue) => { return accumulator + currentValue; } , 0);
如您所见,reduce方法多次执行回调函数。对于每一次,它都取数组中该项的当前值,并与累加器相加。为了正确地求和,你需要将累加器的初始值设置为reduce方法的第二个参数。
现在你有了新的const sum值为30。
Reduce函数在集合上迭代
arr = [{x:1},{x:2},{x:4}] // is a collection
arr.reduce(function(a,b){return a.x + b.x})
翻译:
arr.reduce(
//for each index in the collection, this callback function is called
function (
a, //a = accumulator ,during each callback , value of accumulator is
passed inside the variable "a"
b, //currentValue , for ex currentValue is {x:1} in 1st callback
currentIndex,
array
) {
return a.x + b.x;
},
accumulator // this is returned at the end of arr.reduce call
//accumulator = returned value i.e return a.x + b.x in each callback.
);
在每次索引回调期间,变量accumulator的值为 在回调函数中传入"a"参数。如果不初始化"accumulator",它的值将是undefined。调用定义。X会给出误差。 要解决这个问题,初始化“accumulator”,值为0,如Casey的答案所示。
为了理解“reduce”函数的输入输出,我建议您查看该函数的源代码。 Lodash库有reduce函数,它的工作原理与ES6中的“reduce”函数完全相同。
以下是链接: 减少源代码
//fill创建包含n元素的数组 //reduce需要2个参数,第3个参数作为长度 var fibonacci = (n) =>数组(n).fill()。Reduce ((a, b, c) => { 返回a.concat(c < 2 ?C: a[C - 1] + a[C - 2]) },[]) console.log(斐波纳契(8))