JavaScript 数组 reduce & reduceRight:将数组简化为一个值

摘要:在本教程中,您将学习如何使用 JavaScript 数组 reduce()reduceRight() 方法将数组简化为一个值。

JavaScript 数组 reduce() 方法介绍

假设您有一个包含数字的 数组,例如

let numbers = [1, 2, 3];Code language: JavaScript (javascript)

您想要计算数组元素的总和。

通常,您使用 for 循环 迭代元素并将它们加起来,如下面的示例所示

let numbers = [1, 2, 3];

let sum = 0;
for (let i = 0; i < numbers.length; i++) {
    sum += numbers[i];
}

console.log(sum);Code language: JavaScript (javascript)

输出

6

脚本简单明了

  • 首先,声明一个包含三个数字 1、2 和 3 的数组。
  • 其次,声明 sum 变量 并将其值设置为零。
  • 第三,在 for 循环中,将 numbers 数组的元素加到 sum 变量中。在循环结束后,sum 变量的值为 6。

我们所做的是将数组简化为一个值。

Array.prototype 允许您使用 reduce() 方法将数组简化为单个值,如下所示

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

console.log(sum);Code language: JavaScript (javascript)

很简单,对吧?

让我们详细了解一下 reduce() 方法。

JavaScript 数组 reduce() 方法详解

下面说明了 reduce() 方法的语法

array.reduce(callbackFn [, initialValue])Code language: CSS (css)

reduce() 方法接受两个参数

  • 一个 回调函数 callbackFn。此函数通常被称为 reducer。
  • 一个可选的初始值。

reduce() 方法为数组中的每个元素调用 callbackFn() 函数。

reducer() 函数返回一个值,该值是通过对整个数组执行 callbackFn 得到的。

1) 回调函数 callbackFn() 参数

callbackFn 函数具有以下语法

function callbackFn(previousValue, currentValue, currentIndex, array) { /**/}Code language: PHP (php)

callbackFn 函数接受四个参数

previousValue

从前一次调用 callbackFn 函数返回的值。在第一次调用时,如果传递了 initialValue,则 previousValueinitialValue。否则,它的值为 array[0]

currentValue

当前数组元素的值。在第一次调用时,如果传递了 initialValue,则为 array[0];否则为 array[1]

currentIndex

currentValue 在数组中的索引。在第一次调用时,如果传递了 initialValue,则为 0;否则为 1

array

要循环遍历的数组。

2) initialValue 参数

initialValue 参数是可选的。

如果指定了 initialValue,则 callbackFn 函数将在第一次调用时将 previousValue 初始化为 initialValue,并将 currentValue 初始化为第一个数组元素。

如果没有指定 initialValue,则 callbackFn 函数将在第一次调用时将 previousValue 初始化为第一个数组元素 (array[0]),并将 currentValue 初始化为第二个数组元素 (array[1])。

下表说明了 reduce() 方法在第一次执行 callbackFn() 函数时根据 initialValue 参数进行的逻辑判断

initialValue previousValue currentValue
已传递initialValuearray[0]
未传递array[0]array[1]

以下示例展示了 initialValue 为 100 时 reduce() 函数的执行过程

let numbers = [1, 2, 3];

function getOrdinalSuffix(i) {
  let j = i % 10, k = i % 100;
  if (j == 1 && k != 11) return i + 'st';
  if (j == 2 && k != 12) return i + 'nd';  
  if (j == 3 && k != 13) return i + 'rd';
  return i + 'th';
}

let call = 1;
let sum = numbers.reduce(function (previousValue, currentValue, currentIndex, array) {
    let result = previousValue + currentValue;

    // show the 1st call, 2nd call, etc.
    console.log(`${getOrdinalSuffix(call)} call`);
    call++;

    // show the immediate values
    console.table({ previousValue, currentValue, currentIndex, result });

    return result;
},100);

console.log(`Result: ${sum}`);Code language: JavaScript (javascript)

输出

1st call
┌───────────────┬────────┐
│    (index)    │ Values │
├───────────────┼────────┤
│ previousValue │  100   │
│ currentValue  │   1    │
│ currentIndex  │   0    │
│    result     │  101   │
└───────────────┴────────┘
2nd call
┌───────────────┬────────┐
│    (index)    │ Values │
├───────────────┼────────┤
│ previousValue │  101   │
│ currentValue  │   2    │
│ currentIndex  │   1    │
│    result     │  103   │
└───────────────┴────────┘
3rd call
┌───────────────┬────────┐
│    (index)    │ Values │
├───────────────┼────────┤
│ previousValue │  103   │
│ currentValue  │   3    │
│ currentIndex  │   2    │
│    result     │  106   │
└───────────────┴────────┘
Result: 106Code language: plaintext (plaintext)

以下展示了没有 initialValue 参数的 reduce() 方法

1st call
┌───────────────┬────────┐
│    (index)    │ Values │
├───────────────┼────────┤
│ previousValue │   1    │
│ currentValue  │   2    │
│ currentIndex  │   1    │
│    result     │   3    │
└───────────────┴────────┘
2nd call
┌───────────────┬────────┐
│    (index)    │ Values │
├───────────────┼────────┤
│ previousValue │   3    │
│ currentValue  │   3    │
│ currentIndex  │   2    │
│    result     │   6    │
└───────────────┴────────┘
Result: 6Code language: plaintext (plaintext)

更多 JavaScript 数组 reduce() 示例

假设您有以下 shoppingCart 数组,其中包含产品对象

let shoppingCart = [
  {
    product: 'phone',
    qty: 1,
    price: 500,
  },
  {
    product: 'Screen Protector',
    qty: 1,
    price: 10,
  },
  {
    product: 'Memory Card',
    qty: 2,
    price: 20,
  },
];Code language: JavaScript (javascript)

要计算购物车中产品的总金额,您可以使用 reduce() 方法,如下所示

let total = shoppingCart.reduce(function (previousValue, currentValue) {
  return previousValue + currentValue.qty * currentValue.price;
}, 0);Code language: JavaScript (javascript)

输出

550

请注意,在此示例中,我们向 reduce() 方法传递了 initialValue 参数。

如果我们没有这样做,reduce() 方法将把 shoppingCart 数组的第一个元素(一个对象)作为初始值,并在该对象上执行计算。因此,会导致错误的结果。

JavaScript 数组 reduceRight() 方法

reduceRight() 方法的工作方式与 reduce() 方法相同,但方向相反。

reduce() 方法从第一个元素开始,向后遍历至最后一个元素,而 reduceRight() 方法从最后一个元素开始,向前遍历至第一个元素。

请看下面的示例

let numbers = [1, 2, 3];

let sum = numbers.reduceRight(function (previousValue, currentValue) {
  console.log({ previousValue, currentValue });
  return previousValue + currentValue;
});

console.log(`Result:${sum}`);Code language: JavaScript (javascript)

输出

{ previousValue: 3, currentValue: 2 }
{ previousValue: 5, currentValue: 1 }
Result:6Code language: CSS (css)

下图展示了 reduce() 方法和 reduceRight() 方法之间的区别

javascript array reduce

在本教程中,您已经学习了如何使用 JavaScript 数组 reduce()reduceRight() 方法将数组简化为一个值。

本教程对您有帮助吗?