假设我想对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作为累加器,相反,你可以这样做 ' arr = [{x:1},{x:2},{x:4}]

Arr.reduce(函数(a,b){a + b.x},0) '

其他回答

在reduce的每一步中,你不会返回一个新的{x:??}对象。所以你要么需要做:

arr = [{x:1},{x:2},{x:4}]
arr.reduce(function(a,b){return a + b.x})

或者你需要这样做

arr = [{x:1},{x:2},{x:4}]
arr.reduce(function(a,b){return {x: a.x + b.x}; }) 

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

以下是链接: 减少源代码

泛型typescript函数:

const sum = <T>(array: T[], predicate: (value: T, index: number, array: T[]) => number) => {
      return array.reduce((acc, value, index, array) => {
        return acc + predicate(value, index, array);
      }, 0);
    };

例子:

const s = sum(arr, (e) => e.x);

在第一次迭代之后,你返回一个数字,然后试图获得它的属性x,以添加到下一个对象,这是未定义的,数学涉及未定义的结果在NaN。

尝试返回一个包含x属性和参数x属性的对象:

var arr = [{x:1},{x:2},{x:4}];

arr.reduce(function (a, b) {
  return {x: a.x + b.x}; // returns object with property x
})

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

// -> {x: 7}

评论中增加的解释:

[]的每次迭代的返回值。Reduce作为下一次迭代的a变量。

迭代1:a = {x:1}, b = {x:2}, {x: 3}分配给迭代2中的a

迭代2:a = {x:3}, b = {x:4}。

你的例子的问题是你返回的是一个数字文字。

function (a, b) {
  return a.x + b.x; // returns number literal
}

迭代1:a = {x:1}, b = {x:2}, //在下一次迭代中返回3作为a

迭代2:a = 3, b = {x:2}返回NaN

数字文字3(通常)没有名为x的属性,因此它是未定义的,未定义+ b.x返回NaN, NaN + <任何>总是NaN

澄清:我更喜欢我的方法,而不是这个帖子中的其他答案,因为我不同意通过一个可选参数来减少一个神奇的数字来获得一个数字原语的想法。这可能会导致写的行数更少,但在我看来,可读性更差。

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

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

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