假设我想对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

第一个例子中我做错了什么?


当前回答

一个更简洁的方法是提供一个初始值作为reduce的第二个参数:

Var arr = [{x:1}, {x:2}, {x:4}]; Var结果= arr。Reduce(函数(acc, obj){返回acc + obj.x;}, 0); console.log(结果);/ / 7

第一次调用匿名函数时,使用(0,{x: 1})调用它,并返回0 + 1 = 1。下一次,它被(1,{x: 2})调用,并返回1 + 2 = 3。然后用(3,{x: 4})调用它,最后返回7。

这也可以处理数组为空的情况,返回0。

其他回答

一个更简洁的方法是提供一个初始值作为reduce的第二个参数:

Var arr = [{x:1}, {x:2}, {x:4}]; Var结果= arr。Reduce(函数(acc, obj){返回acc + obj.x;}, 0); console.log(结果);/ / 7

第一次调用匿名函数时,使用(0,{x: 1})调用它,并返回0 + 1 = 1。下一次,它被(1,{x: 2})调用,并返回1 + 2 = 3。然后用(3,{x: 4})调用它,最后返回7。

这也可以处理数组为空的情况,返回0。

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”函数完全相同。

以下是链接: 减少源代码

对于第一次迭代,'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)

您可以使用减少方法如下所示;如果您将0(零)更改为1或其他数字,它会将其添加到总数中。例如,这个例子给出的总数是31,但是如果我们把0改为1,总数将是32。

const batteryBatches = [4, 5, 3, 4, 4, 6, 5];

let totalBatteries= batteryBatches.reduce((acc,val) => acc + val ,0)

我在ES6中做了一点改进:

arr.reduce((a, b) => ({x: a.x + b.x})).x

返回数