js-reduce()方法详细讲解

753 阅读3分钟

基本概念

reduce()方法在数组中从左到右工作,为每一个元素依次执行回调函数(不包括数组中被删除或从未被赋值的元素)。

参数解析

使用语法: arr.reduce(callback,[initialValue])

  • callback (执行数组中每个元素的函数,包含四个参数)
    • previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
    • currentValue (数组中当前被处理的元素)
    • index (当前元素在数组中的索引)
    • array (调用 reduce 的数组)
  • initialValue (作为第一次调用 callback 的第一个参数。)

基础用法(示例)

未设置初始值情况

let arr = [2, 4, 6]
let sum = arr.reduce((prev, cur, index, array) => {
  console.log('prev: ', prev)
  console.log('cur: ', cur)
  console.log('index: ', index)
  console.log('array: ', array)
  console.log('----------------')
  return prev + cur
})
/*
	数组中有三位元素,但函数只会执行两次,具体如下。
	
	第一次执行输出:
	prev:  2  // 由于未设置初始值,所以第一次执行prev为数组第一个元素2
	cur:  4 //数组第二个元素为当前被处理的元素
	index:  1 //当前被处理元素4对应的下标
	array:  [ 2, 4, 6 ] // 调用reduce的数组
	----------------
	
	第二次执行输出:
	prev:  6 //上一次调用回调return的值,2 + 4 = 6,所以此处prev为6
	cur:  6 //数组元素由左到右依次进行处理,此处处理数组的第三个元素6
	index:  2 // 当前被处理元素6对应的下标
	array:  [ 2, 4, 6 ] // 调用reduce的数组
	----------------
	
	arr => [2, 4, 6]
	sum => 12
*/

设置初始值情况

let arr = [2, 4, 6]
let sum = arr.reduce((prev, cur, index, array) => {
  console.log('prev: ', prev)
  console.log('cur: ', cur)
  console.log('index: ', index)
  console.log('array: ', array)
  console.log('----------------')
  return prev + cur
},10)
/*
	设置初始值,函数执行3次,具体如下。
	
	第一次执行输出:
	prev:  10  // 此处设置了初始值10
	cur:  2 //由左到右,数组第一个元素2
	index:  0 //当前被处理元素2对应的下标
	array:  [ 2, 4, 6 ] // 调用reduce的数组
	----------------
	
	第二次执行输出:
	prev:  12 //上一次调用回调return的值,10 + 2 = 12,所以此处prev为12
	cur:  4 //由左到右依次进行处理,此处处理数组的第二个元素4
	index:  1 // 当前被处理元素4对应的下标
	array:  [ 2, 4, 6 ] // 调用reduce的数组
	----------------
	
	第三次执行输出:
	prev:  16 //上一次调用回调return的值,12 + 4 = 16,所以此处prev为16
	cur:  6 //由左到右依次进行处理,此处处理数组的第三个元素6
	index:  2 // 当前被处理元素6对应的下标
	array:  [ 2, 4, 6 ] // 调用reduce的数组
	----------------
	
	arr => [2, 4, 6]
	sum => 22
*/

基本用法如上,自己动手实践一遍,就可以大致有些了解,以下会介绍一些实际应用。

实际应用

数组求和,求积

let arr = [1, 2, 3]
let sum = arr.reduce((prev, cur) => prev + cur)
let mul = arr.reduce((prev, cur) => prev * cur)

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

// 不使用reduce方法
let arr = ['a', 'b', 'c', 'a', 'c']
let obj = {}
arr.forEach(item => {
  if (item in obj) {
    obj[item]++
  } else {
    obj[item] = 1
  }
})
// obj => { a: 2, b: 1, c: 2 }

// 使用reduce
let res = arr.reduce((prev, cur) => {
  if (cur in prev) {
    prev[cur]++
  } else {
    prev[cur] = 1
  }
  return prev
}, {})
// res => { a: 2, b: 1, c: 2 }

数组去重

let arr = [5, 1, 1, 2, 3, 4, 3, 5]
// Set方法
let res = Array.from(new Set(arr)) // res => [ 5, 1, 2, 3, 4 ]

// forEach方法
let resArr = []
arr.forEach(item => {
  if (!resArr.includes(item)) {
    resArr.push(item)
  }
}) // resArr => [ 5, 1, 2, 3, 4 ]

// reduce方法
let resArr = arr.reduce((prev, cur) => {
  if (!prev.includes(cur)) {
    prev.push(cur)
    // prev.concat(cur)
  }
  return prev
}, []) // resArr => [ 5, 1, 2, 3, 4 ]

将多维数组转化为一维数组

let arr = [ [0, 1], [2, 3], [4, 5, [2, 3]] ]
// flat()
let res = arr.flat(Infinity) // res => [0, 1, 2, 3, 4, 5, 2, 3]

// reduce()
const flat = (item) => {
  let res = item.reduce((prev, cur) => {
    if (cur instanceof Array) {
    // Array.isArray(cur) <=> cur instanceof Array
      return prev.concat(flat(cur))
    } else {
      return prev.concat(cur)
    }
  }, [])
  return res
}
// flat(arr) => [0, 1, 2, 3, 4, 5, 2, 3]

暂时总结这些实际应用用法,后面会持续更新。