假设我想对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的值将是1,b的值将是2,但由于2+1将返回,在下一步中,b的值将是第一步的返回值,即3,因此b.x将是未定义的…而undefined + anyNumber将是NaN,这就是为什么你会得到这个结果。

相反,你可以尝试给初始值为零,即

arr.reduce(function(a,b){return a + b.x},0);

其他回答

你不应该使用a.x作为累加器,相反,你可以这样做 ' arr = [{x:1},{x:2},{x:4}]

Arr.reduce(函数(a,b){a + b.x},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。

泛型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);
function aggregateObjectArrayByProperty(arr, propReader, aggregator, initialValue) {
  const reducer = (a, c) => {
    return aggregator(a, propReader(c));
  };
  return arr.reduce(reducer, initialValue);
}

const data = [{a: 'A', b: 2}, {a: 'A', b: 2}, {a: 'A', b: 3}];

let sum = aggregateObjectArrayByProperty(data, function(x) { return x.b; }, function(x, y) { return x + y; }, 0);
console.log(`Sum = ${sum}`);
console.log(`Average = ${sum / data.length}`);

let product = aggregateObjectArrayByProperty(data, function(x) { return x.b; }, function(x, y) { return x * y; }, 1);
console.log(`Product = ${product}`);

只是根据之前给出的解写了一个泛型函数。我是一名Java开发人员,所以为任何错误或非javascript标准道歉:-)

我在ES6中做了一点改进:

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

返回数