深度理解数组的reduce方法

176 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情

说起数组的reduce方法大家都知道可以用来给数组求和,除了数组求和还可以利用reduce做些什么事情呢?通过这篇文章结合几个案例和大家一起学习一下数组的reduce方法

reduce方法

reduce()  方法对数组中的每个元素按序执行一个由您提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。

第一次执行回调函数时,不存在“上一次的计算结果”。如果需要回调函数从数组索引为 0 的元素开始执行,则需要传递初始值。否则,数组索引为 0 的元素将被作为初始值 init,迭代器将从第二个元素开始执行(索引为 1 而不是 0)。

下面是api的使用和每个参数代表的含义:

arr.reduce((prev,curr,index,arr)=>{

},init)
  • arr: 用于遍历的数组
  • prev: 上一次调用回调时的返回值,在第一次调用时,若指定了初始值 init,其值则为 init,否则为数组索引为 0 的元素 array[0]
  • curr: 数组正在处理的元素。在第一次调用时,若指定了初始值 init,其值则为数组索引为 0 的元素 array[0],否则为 array[1]
  • index:数组正在处理的元素的索引,若提供init值,则起始索引号为 0,否则从索引 1 起始。
  • init: 初始值

案例

数组求和

例1

const arr = [1,2,3,4,5,6]
const sum = arr.reduce((prev,curr)=>{
    return prev +curr
})
console.log(sum)
// 结果为21

例2

const arr = [1,2,3,4,5,6]
const sum = arr.reduce((prev,curr)=>{
return prev +curr
},2)
console.log(sum)
// 结果为23

数组求和是reduce方法最常见的使用案例了,很多人只知道返回prev + curr就能返回总和,这也是最普遍的用法,例2 我们设置初始值init为2,结果为23,这是因为设置初始值为2 从2开始加所以是23

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

let person = ['库里','科比','韦德','库里','杜兰特','莫兰特']
let nameObj = person.reduce((prev,curr) =>{
if( curr in prev){
    prev[curr]++
}
else{
    prev[curr] = 1
}
    return prev
}, {})
console.log(nameObj) 
// {"库里": 2, "科比": 1,"韦德": 1,"杜兰特": 1,"莫兰特": 1}

数组扁平化

例1

const arr2 = [1,[2,[3,[4,5]]],6]
const newArr = (arr) => {
    return arr.reduce((prev,curr)=>{
        return prev.concat(Array.isArray(curr) ? newArr(cur) : cur)
    },[])
}
console.log(newArr(arr2)) // [1, 2, 3, 4, 5, 6]

例2

const data = [
  {
    id: 1,
    name: '勇士',
    children: [
      {
        id: 33,
        name: '库里',
        children: [
          {
            id: 111,
            name: '莱利'
          },
          {
            id: 112,
            name: '卡侬'
          }
        ]
      }
    ]
  },
  {
    id: 2,
    name: '湖人',
    children: [
      {
        id: 23,
        name: '詹姆斯',
        children: [
          {
            id: 211,
            name: '布朗尼'
          },
          {
            id: 212,
            name: '布莱克'
          }
        ]
      }
    ]
  }
]
const result = data.reduce(function (prev, curr) {
  prev.push({
    id:curr.id,
    name: curr.name,
    parentId: curr.parentId
  })
  curr.children && curr.children.forEach(v=>{
    v.parentId = curr.id
    arguments.callee(prev,v) 
    //callee  arguments 对象的一个属性。
    //它可以用于引用该函数的函数体内当前正在执行的函数。这在函数的名称是未知时很有用,例如在没有名称的函数表达式 (也称为“匿名函数”) 内。
  })
  return prev
}, [])
console.log('转换前', data)
console.log('转换后', result)

实现数组扁平化的方式不止这两种,大家根据自身数据结构选择合适的方法

扁平化数组转换为树状结构

基于数组扁平化例2 resulat数据

const data = 例2result

const result = data.reduce(function (prev,curr,index,arr) {
  curr.children = arr.filter(v => v.parentId === curr.id)
  if(!curr.parentId){
    prev.push(curr)
  }
  return prev
}, [])
console.log(result)

数组去重

const arr3 = [1,2,3,4,5,3,2,1,6,4,7,8]
const resultArr = arr3.reduce((prev,curr)=>{
if(!prev.includes(curr)){
    return prev.concat(curr)
}
else{
    return prev
}
},[])
console.log(resultArr)

以上大概涵盖了reduce方法的基本使用,快快掌握吧