数组中的reduce犹如一只魔法棒,通过它能够做一些黑科技一样的事件。本文从api解说到个别用法再到高级用法,由浅入深的讲一讲数组中的reduce。MDN链接

Array.prototype.reduce

reduce的api是这样的,

reduce(callback(accumulator, currentValue[, index, array])[,initialValue])
  • Callback

    • accumulator 积攒的值
    • currentValue 以后值
    • index 以后下标
    • array 以后数组
  • initialValue 初始值

reduce承受两个参数,回调函数和初识值,初始值是可选的。回调函数承受4个参数:积攒值、以后值、以后下标、以后数组。
如果reduce的参数只有一个,那么积攒值一开始是数组中第一个值,如果reduce的参数有两个,那么积攒值一开始是出入的initialValue初始值。
而后在每一次迭代时,返回的值作为下一次迭代的accumulator 积攒值。

重要阐明:如果未设置initialValue,那么reduce将应用您的第一个数组值作为第一次迭代的accumulator,从第二个数组元素上开始循环,从index=1开始(如果有的话)

以下是reduce的几种理论利用。

1. 将数组转化为对象

将上面的数组转成以id为key的对象。

const userList = [    {        id: 1,        username: 'john',        sex: 1,        email: 'john@163.com'    },    {        id: 2,        username: 'jerry',        sex: 1,        email: 'jerry@163.com'    },    {        id: 3,        username: 'nancy',        sex: 0,        email: ''    }];let objUserList = userList.reduce(keyByUserNameReducer, {})function keyByUserNameReducer(acculumator, currentValue, currentIndex, array) {    return {...acculumator, [currentValue.id]: currentValue}}console.log(objUserList)// {//    '1': { id: 1, username: 'john', sex: 1, email: 'john@163.com' },//    '2': { id: 2, username: 'jerry', sex: 1, email: 'jerry@163.com' },//    '3': { id: 3, username: 'nancy', sex: 0, email: '' }// }

2. 将小数组开展成大数组

将上面数组依照逗号宰割.

const fileLines = [    'Inspector Algar,Inspector Bardle,Mr. Barker,Inspector Barton',    'Inspector Baynes,Inspector Bradstreet,Inspector Sam Brown',    'Monsieur Dubugue,Birdy Edwards,Inspector Forbes,Inspector Forrester',    'Inspector Gregory,Inspector Tobias Gregson,Inspector Hill',    'Inspector Stanley Hopkins,Inspector Athelney Jones'];let commaArray = fileLines.reduce(function (acculumator, currentValue, currentIndex, array) {    return acculumator.concat(currentValue.split(/,/g))}, [])console.log(commaArray)/*[    'Inspector Algar',    'Inspector Bardle',    'Mr. Barker',    'Inspector Barton',    'Inspector Baynes',    'Inspector Bradstreet',    'Inspector Sam Brown',    'Monsieur Dubugue',    'Birdy Edwards',    'Inspector Forbes',    'Inspector Forrester',    'Inspector Gregory',    'Inspector Tobias Gregson',    'Inspector Hill',    'Inspector Stanley Hopkins',    'Inspector Athelney Jones'  ]*/

3. 用reduce实现flatMap

// 数组的flatMap// flatMap的底层的操作:先应用map操作,而后对失去的数组仅开展一层再失去一个数组const arr = ["今天天气不错", "", "早上好"];let flatMapArr = arr.flatMap((item, index) => {    return item.split("")})console.log(flatMapArr) // ['今', '天', '天','气', '不', '错','早', '上', '好']// 应用数组的reduce实现数组的flatMaplet reduceFlatMap = arr.reduce(function (acculumator, currentValue, currentIndex, array) {    return [...acculumator, ...currentValue.split('')]}, [])console.log(reduceFlatMap) // ['今', '天', '天','气', '不', '错','早', '上', '好']

4. 按程序执行异步函数

依据userList数组的name属性去顺次申请数据。

let asyncReducer = userList.reduce(async function (acculumator, currentValue, currentIndex, array) {    const obj = await acculumator.then()    let re = await new Promise((resolve, reject) => {        // 用 setTimeout 模仿申请数组        setTimeout(() => {            resolve(`to=>${currentValue.username}`)        }, 1000)    })    return {...obj, [currentValue.username]: re}}, Promise.resolve({}))asyncReducer.then(res => {    console.log(res)})// 3s之后打印:// { john: 'to=>john', jerry: 'to=>jerry', nancy: 'to=>nancy' }

总结:

  • 记住在解决对象数组时要指定一个initialValue
  • 数字数组应用reduce代码洁净,请尽量不要把reduce函数过于简单
  • 不要遗记在回调函数中返回,否则最初失去的值将可能呈现谬误
  • 回调函数的第三个参数index拜访迭代次数
  • reduce解决时会跳过数组空值