Array 方法 `reduce` 有什么作用?

What does the Array method `reduce` do?

我发现了一个非常有用的函数reduce,我正在使用它,但我不确定我是否理解正确。谁能帮我理解这个功能?

示例:

var arr = [ 1, 2, 3, 4, 5, 6 ];
arr.reduce(function(p,n){
    return p + n;
}, 0);
// Output 21

这是我的理解:reduce循环遍历数组的每个元素和returns previous + current value。前任。 0 + 11 + 2 等。在这种情况下,此函数将 return:

[0] - return 1
[1] - return 3
[2] - return 5
[3] - return 7
[4] - return 9
[5] - return 11

接下来呢?为什么会给出结果 21?

取自 herearr.reduce() 会将数组缩减为回调指定的值。在您的情况下,它基本上会对数组的元素求和。 步骤:

  • 在 0,1 上调用函数(0 是作为第二个参数传递给 .reduce() 的初始值。Return 将 0 和 1 相加,即 1。
  • 对上一个结果(即 1)和下一个数组元素调用函数。这个returns 1和2的和,就是3
  • 重复直到最后一个元素,总和为 21

reduce() 方法有两个参数:一个为数组中的每个元素调用的回调函数和一个初始值。

回调函数还有两个参数:累加器值和当前值。

您的数组 ([1, 2, 3, 4, 5, 6]) 的流程是这样的:

1. return 0 + 1 // 0 is the accumulator which the first time takes the initial value, 1 is the current value. The result of this becomes the accumulator for the next call, and so on..
2. return 1 + 2 // 1 - accumulator, 2 - current value
3. return 3 + 3 // 3 - accumulator, 3 - current value, etc...
4. return 6 + 4
5. return 10 + 5
6. return 15 + 6

到达数组末尾时,return累加器,这里是21

为了更好地理解 reduce 的工作原理,请使用以下 sum(a,b) 函数,该函数会为它执行的每个操作记录一个类似 a+b=c 的文本。

function sum(a,b) { 
  const c = a + b;
  console.log(`${a} + ${b} => ${c}`)
  return c;
}

const arr = [1,2,4,8];
const result = arr.reduce(sum);
console.log(`result=${result}`)

这会打印 1+2=>33+4=>77+8=>15,最后是 result=15

有 2 个极端情况:

  • 仅 1 个元素 --> 仅 returns 个元素。
  • 没有元素,空数组 --> 抛出错误。

一个可能的解决方案是使用初始化程序。

首先,“reduce”这个名字实际上并没有减少任何东西。这是您在编程中经常发现的 confusional/tricky 命名约定。

reduce 是一个高阶函数,它有两个参数:

  1. 回调函数和
  2. 初始值。

回调函数有四个参数:

  1. 上一个值,
  2. 当前值,
  3. currentIndex,
  4. 数组

更多的时候你会发现根据我们要解决的问题,回调函数只需要两个参数,这很好。

[1, 2, 3].reduce((previousValue, currentValue, currentIndex, array) => {
  // here the return statement goes...
}, initialValue);

现在让我们看一个实际的例子。编写一个程序来 return 数组中所有元素的总和。请先考虑as-usual way/procedure,然后我们再用reduce解决同样的问题。下面是写这个程序的as-usualway/procedure:

function sum(arr) {
  let sum = 0;
  for(let i = 0; i < array.length; i++) {
    sum = sum + arr[i];
  }
  return sum;
}

因此,如果我们用数组调用 sum,它将 return 所有元素的总和。对吗?

是的,我们也可以用 reduce 做同样的事情。这是代码:

[1, 2, 3, 4].reduce(function(previousValue, currentValue) {
  let result = previousValue + currentValue;
  return result;
}, 0);

它做同样的事情。 reducer 遍历数组元素,在每一步将当前数组值添加到上一步的结果(这个结果是所有前面步骤的 运行 总和)——直到没有更多元素要添加。 (参考:here

这里的previousValue是as-usualsumcurrentValue是as-usualarr[i].

在第一次迭代中,没有 previousValue (return value of the previous calculation) - 对吗?在这种情况下,initialValue 将用作 previousValue。如果没有initialValue,索引为0的数组元素作为初始值,从下一个元素开始迭代(索引1而不是索引0)。

不用额外的变量result,你可以这样写程序:

[1, 2, 3, 4].reduce(function(previousValue, currentValue) {
  previousValue += currentValue;
  return previousValue;
}, 0);

还有更短的时间:

[1, 2, 3, 4].reduce((previousValue, currentValue) => previousValue += currentValue, 0);

希望你明白。现在你的任务是编写一个程序,该程序将使用 reduce 从 non-empty 数组中找到最小数字(考虑数组中的所有元素都是正数)。

这里是:

const arr = [4, 2, 3, 1];
let result = arr.reduce((minValue, currentValue) => {
  if (currentValue < minValue) {
    minValue = currentValue;
  }
  return minValue;
}); // no initial value 
console.log(result);

❤️ 快乐编码❤️