Array方法`reduce`是什么意思?

8
我发现了一个非常有用的函数reduce,并且我正在使用它,但我不确定我是否正确理解它。 有人能帮助我理解这个函数吗?
示例:
var arr = [ 1, 2, 3, 4, 5, 6 ];
arr.reduce(function(p,n){
    return p + n;
}, 0);
// Output 21

这是我的理解:reduce 循环遍历数组的每个元素,并返回前一个值 + 当前值。例如,0 + 11 + 2 等。在这种情况下,该函数将返回:
[0] - return 1
[1] - return 3
[2] - return 5
[3] - return 7
[4] - return 9
[5] - return 11

下一步是什么?为什么它会给出结果21

5
当你不理解它时......读文档 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce - charlietfl
reduce() 方法将一个函数应用于累加器和数组的每个值(从左到右),以将其减少为单个值。 - zwergmaster
MDN 每次迭代都有清晰美观的解释。 - Tushar
6
CharlieTF - 我已经尝试了,但仍然不理解。这就是为什么我会问的原因。 - Steave
减少(Reduce)是动态规划,我告诉你啊 :3 - gawkface
6个回答

14

这里获取,arr.reduce()将通过回调函数将数组减少为一个值。在您的情况下,它将基本上对数组元素求和。
步骤:

  • 在0,1上调用函数(0是作为第二个参数传递给.reduce()的初始值)。返回0和1的总和,即1。
  • 在先前的结果(即1)和下一个数组元素上调用函数。这将返回1和2的总和,即3。
  • 重复此过程,直到最后一个元素,最终总和为21。

1
现在我明白了。我以为我的例子中的“p”是数组的先前值。谢谢! - Steave
顺便提一下,在这个例子中,初始值(即0)是可选的,如果省略它,将得到相同的结果,但少调用一个函数。 - skube

10

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

当到达数组的末尾时,返回累加器,这里是21


干运行是从“计算机科学导论”开始的基本概念,它可以帮助您识别算法的流程甚至复杂性。@Steave - Dynamic Remo

3
首先,"reduce"这个名称实际上并不会减少任何东西。在编程中,您经常会发现这种困惑/棘手的命名约定。虽然为了更好地理解,您可以假设它从多个值中获取值并将其缩小为单个值并返回。
reduce是一个高阶函数,它接受两个参数:
1. 回调函数和 2. 初始值
回调函数需要四个参数:
1. 上一个值(previousValue) 2. 当前值(currentValue) 3. 当前索引(currentIndex) 4. 数组(array)
根据我们需要解决的问题,通常情况下您只需按照两个参数传递回调函数即可。
[1, 2, 3].reduce((previousValue, currentValue, currentIndex, array) => {
  // here the return statement goes...
}, initialValue);

现在让我们来看一个具体的例子。编写一个程序,返回数组中所有元素的总和。请先按常规方法/过程思考,然后我们将使用 reduce 来解决同样的问题。以下是编写此程序的常规方法/过程:

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

所以,如果我们使用一个数组调用sum函数,它将返回所有元素的总和。是这样吗?

是的,我们也可以使用reduce完成相同的操作。下面是代码:

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

它做的事情相同。reducer遍历数组元素,在每一步中将当前数组值添加到上一步的结果中(该结果是所有先前步骤的运行总和),直到没有更多要添加的元素为止。(引用:这里
在这里,previousValue是惯常的sum ,而currentValue是惯常的arr[i]
在第一次迭代中,没有previousValue(先前计算的返回值) - 对吗?在这种情况下,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方法找到非空数组中的最小值(假设数组中所有元素都是正数)。

以下是示例代码:

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);

❤️ 快乐编程 ❤️


1
为了更好地理解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=>3, 3+4=>7, 7+8=>15 最后result=15
有两个特殊情况:
  • 只有一个元素 --> 返回该元素。
  • 没有元素,空数组 --> 抛出错误。
一种可能的解决方案是使用初始化程序。

initializer


0
以上所有答案都解释了arr.reduce()仅适用于加法,如果我想使用reduce执行其他操作,例如减法、乘法等,该怎么办呢?
在这种情况下,reduce将如何在后台执行?

Here is the detailed explanation to the answer:

function reduce(array, iterator, initialValue) {
    const isInitialValueDefined = typeof initialValue !== "undefined";
    if (!isInitialValueDefined && array.length === 0) {
        throw new TypeError("Reduce of empty array with no initial value");
    }
    let acc = isInitialValueDefined ? initialValue : array[0];
    for (let i = isInitialValueDefined ? 0 : 1; i < array.length; i++) {
        acc = iterator(acc, array[i], i, array);
    }
    return acc;
}

console.log(reduce([1, 2, 3, 4], (a, i) => a + i)); // => 10
console.log(reduce([1, 2, 3, 4], (a, i) => a * i, 1)); // => 24
console.log(reduce([], (a, i) => a + i)); // => TypeError

reduce()是一个接受两个参数的函数:

  1. 回调函数
  2. 初始值

回调函数接受四个参数:

  1. 前一个值
  2. 当前值
  3. 当前索引
  4. 数组

大多数情况下,你会发现回调函数只接受2个参数。


0
Reduce函数:Reduce函数并不会减少任何东西。Reduce是将数组的所有元素取出并从中得出单个值的函数。 在此输入图像描述

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接