Array.reduce() 详解

本文详细介绍了JavaScript数组的reduce()方法,包括其参数、回调函数的工作原理以及不同情况下的处理方式。reduce()用于遍历数组并执行回调函数,回调函数接收四个参数:previousValue、currentValue、currentIndex和数组本身。initialValue可选,影响回调函数的初始调用状态。当数组为空且未指定初始值时,会抛出TypeError。reduce()在数组操作中广泛应用,如求和、转化数组、计数、去重和实现高效的一次遍历操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

reduce()方法是数组原型上的方法(Array.prototype.reduce())

reduce(callbackFn,initialValue)有两个参数

第一个参数是一个callbackFn,我们就叫做reduce 回调函数,由用户自己提供

callbackFn(reduce 回调函数)有四个参数: 一个 “reducer” 函数,包含四个参数:

  1. previousValue:上一次调用 callbackFn 时的返回值。在第一次调用时,若指定了初始值 initialValue,其值则为 initialValue,否则为数组索引为 0 的元素 array[0]。
  2. currentValue:数组中正在处理的元素。在第一次调用时,若指定了初始值 initialValue,其值则为数组索引为 0 的元素 array[0],否则为 array[1]。
  3. currentIndex:数组中正在处理的元素的索引。若指定了初始值 initialValue,则起始索引号为 0,否则从索引 1 起始。
  4. array:调用reduc()的数组本身。

第二个参数 initialValue(初始值)可选的

作为第一次调用 callback 函数时参数 previousValue 的值。若指定了初始值 initialValue,则 currentValue 则将使用数组第一个元素;否则 previousValue 将使用数组第一个元素,而 currentValue 将使用数组第二个元素。

Array.reduce(callbackFn,initialValue) 是遍历数组,遍历一次就zh执行一次callback函数,

  • 回调函数第一次执行时,previousValue 和 currentValue 的取值有两种情况:
    1.如果调用 reduce() 时提供了 initialValue,previousValue 取值则为 initialValue,currentValue 则取数组中的第一个值。
    2.如果没有提供 initialValue,那么 previousValue 取数组中的第一个值,currentValue 取数组中的第二个值。
  • 每次执行callback函数的返回值会作为下一次调用callback函数的第一个参数,数组中还未被处理的第一个成员将作为第二个参数,直至最后一次调用callback函数,最终的返回结果将作为Array.reduce()的返回值

如果数组为空且未指定初始值 initialValue,则会抛出 TypeError。

如果数组仅有一个元素(无论位置如何)并且没有提供初始值 initialValue,或者有提供 initialValue 但是数组为空,那么此唯一值将被返回且 callbackfn 不会被执行。

例如:
数组求和

let sum = [0, 1, 2, 3].reduce(function (previousValue, currentValue) {
  return previousValue + currentValue
}, 0)
// sum is 6

将二维数组转化为一维

let flattened = [[0, 1], [2, 3], [4, 5]].reduce(
  function(previousValue, currentValue) {
    return previousValue.concat(currentValue)
  },
  []
)
// flattened is [0, 1, 2, 3, 4, 5]

计算数组中每个元素出现的次数

let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice']
let countedNames = names.reduce(function (allNames, name) {
  if (name in allNames) {
    allNames[name]++
  }
  else {
    allNames[name] = 1
  }
  return allNames
}, {})
// countedNames is:
// { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }

数组去重

let myArray = ['a', 'b', 'a', 'b', 'c', 'e', 'e', 'c', 'd', 'd', 'd', 'd']
let myArrayWithNoDuplicates = myArray.reduce(function (previousValue, currentValue) {
  if (previousValue.indexOf(currentValue) === -1) {
    previousValue.push(currentValue)
  }
  return previousValue
}, [])

console.log(myArrayWithNoDuplicates)

使用 .reduce() 替换 .filter().map()
使用 Array.filter() 和 Array.map() 会遍历数组两次,而使用具有相同效果的 Array.reduce() 只需要遍历一次,这样做更加高效。(如果你喜欢 for 循环,你可用使用 Array.forEach() 以在一次遍历中实现过滤和映射数组)

const numbers = [-5, 6, 2, 0];

const doubledPositiveNumbers = numbers.reduce((previousValue, currentValue) => {
  if (currentValue > 0) {
    const doubled = currentValue * 2;
    previousValue.push(doubled);
  }
  return previousValue;
}, []);

console.log(doubledPositiveNumbers); // [12, 4]

使用函数组合实现管道

// Building-blocks to use for composition
const double = x => x + x
const triple = x => 3 * x
const quadruple = x => 4 * x

// Function composition enabling pipe functionality
const pipe = (...functions) => initialValue => functions.reduce(
    (acc, fn) => fn(acc),
    initialValue
)

// Composed functions for multiplication of specific values
const multiply6 = pipe(double, triple)
const multiply9 = pipe(triple, triple)
const multiply16 = pipe(quadruple, quadruple)
const multiply24 = pipe(double, triple, quadruple)

// Usage
multiply6(6)   // 36
multiply9(9)   // 81
multiply16(16) // 256
multiply24(10) // 240
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值