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

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


当前回答

var arr = [{x:1}, {x:2}, {x:3}];
arr.map(function(a) {return a.x;})
.reduce(function(a, b) {return a + b});
console.log(arr);
//I tried using the following code and the result is the data array
//result = [{x:1}, {x:2}, {x:3}];
var arr2 = [{x:1}, {x:2}, {x:3}]
.reduce((total, thing) => total + thing.x, 0);
console.log(arr2);
// and I changed the code to like this and it worked.
// result = 6

其他回答

数组缩减函数接受三个参数,即initialValue(默认值) 它是0),累加器和当前值。 默认情况下,initialValue的值为“0”。这是由 蓄电池

让我们用代码来看看。

var arr =[1,2,4] ;
arr.reduce((acc,currVal) => acc + currVal ) ; 
// (remember Initialvalue is 0 by default )

//first iteration** : 0 +1 => Now accumulator =1;
//second iteration** : 1 +2 => Now accumulator =3;
//third iteration** : 3 + 4 => Now accumulator = 7;
No more array properties now the loop breaks .
// solution = 7

同样的例子还有initial Value:

var initialValue = 10;
var arr =[1,2,4] ;
arr.reduce((acc,currVal) => acc + currVal,initialValue ) ; 
/
// (remember Initialvalue is 0 by default but now it's 10 )

//first iteration** : 10 +1 => Now accumulator =11;
//second iteration** : 11 +2 => Now accumulator =13;
//third iteration** : 13 + 4 => Now accumulator = 17;
No more array properties now the loop breaks .
//solution=17

同样适用于对象数组(当前的stackoverflow问题):

var arr = [{x:1},{x:2},{x:4}]
arr.reduce(function(acc,currVal){return acc + currVal.x}) 
// destructing {x:1} = currVal;
Now currVal is object which have all the object properties .So now 
currVal.x=>1 
//first iteration** : 0 +1 => Now accumulator =1;
//second iteration** : 1 +2 => Now accumulator =3;
//third iteration** : 3 + 4 => Now accumulator = 7;
No more array properties now the loop breaks 
//solution=7

要记住的一件事是InitialValue默认为0,可以给任何我的意思{},[]和数字

其他人已经回答了这个问题,但我认为我应该提出另一种方法。你可以结合一个映射(从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;});

不可否认,它可能会稍微慢一些,但我认为值得把它作为一个选项提出来。

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

以下是链接: 减少源代码

var arr = [{x:1}, {x:2}, {x:3}];
arr.map(function(a) {return a.x;})
.reduce(function(a, b) {return a + b});
console.log(arr);
//I tried using the following code and the result is the data array
//result = [{x:1}, {x:2}, {x:3}];
var arr2 = [{x:1}, {x:2}, {x:3}]
.reduce((total, thing) => total + thing.x, 0);
console.log(arr2);
// and I changed the code to like this and it worked.
// result = 6

如果你有一个包含大量数据的复杂对象,比如一个对象数组,你可以采取一步一步的方法来解决这个问题。

如:

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。