reduce 将数组合并为一个值

reduce combines an array into a single value

我正在阅读 article here

reduce combines an array into a single value by repeatedly using a function that combines an element of the array with a base value. This is exactly what sum did, so it can be made shorter by using reduce... except that addition is an operator and not a function in JavaScript, so we first had to put it into a function.

function reduce(combine, base, array) {
  forEach(array, function (element) {
    base = combine(base, element);
  });
  return base;
}

function add(a, b) {
  return a + b;
}

function sum(numbers) {
  return reduce(add, 0, numbers);
}

function countZeroes(array) {
  function counter(total, element) {
    return total + (element === 0 ? 1 : 0);
  }
  return reduce(counter, 0, array);
}

Reduce 通过函数减少列表。说合并成一个值太廉价了,你可以把它缩减成一个列表。

Reduce 在函数式编程语言中也被称为折叠结构。如果您对折叠 (https://en.wikipedia.org/wiki/Fold_(higher-order_function)) 进行一些研究,然后尝试返回,它可能会更有意义。

reduce 操作通过遍历数组并将 accumulator 呈现给自定义回调来工作。该回调可以随心所欲地随意处理该累加器。例如,累加器通常是回调 添加 的数字。因此,一组数字将减少为一个数字。

Array.prototype.reduce 实际上只是对此的抽象:

var acc = 0;
for (var i = 0; i < arr.length; i++) {
    acc += arr[i];
}

表示为减少:

var acc = arr.reduce(function (acc, n) {
    return acc + n;
});

显然,您不必使用 +,您可以做任何其他事情,例如:

var acc = [];
for (var i = 0; i < arr.length; i++) {
    acc.push(arr[i]);
}

var acc = arr.reduce(function (acc, n) {
    acc.push(n);
    return acc;
}, []);

结果是原来的数组,什么都没有"reduced"。 (是的,这是毫无意义的,但展示了你拥有的自由。)

累加器只是回调 return 在上一次迭代中输入的值。归约操作如下:

  • 回调采用空累加器*和数组的第一个值,returns 值
  • 回调采用 return 前一次迭代的值和数组的第二个值,returns 值
  • [对数组中的每个元素重复]
  • reduce 吐出上次回调的结果作为 reduce 操作的结果

* 有关第一次迭代行为的详细信息,请参阅 API 文档。

除了已接受的答案外,我还想指出 reduce 是一个非常 通用的概念 。它甚至比 mapfilter 更通用,因为您可以从 reduce.

推导出它们

您不仅可以减少像 Numbers 这样的原语,还可以减少几乎所有的东西。作为说明,我给你一个减少功能的例子:

const inc = x => x + 1;
const sqr = x => x * x;
let fs = [inc, sqr];

fs.reduce((f, g) => g(f), 2); // 9

这只是函数组合。因此我们可以利用reduce来组合函数。