详解javascript的reduce()方法,各种场景


语法:array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

参数:

1. function(total,currentValue, currentIndex,arr)  必需。用于执行每个数组元素的函数。

  • total 必需。初始值, 或者计算结束后的返回值。
  • currentValue 必需。当前元素。
  • currentIndex 可选。当前元素的索引。
  • arr 可选。当前元素所属的数组对象。

2. initialValue 可选。传递给函数的初始值

 如何使用?参考如下示例:

1. 实现累加,计算数组里所有值的和

let arr = [1, 2, 3, 4, 5]
let result = arr.reduce((total, currentValue, currentIndex, arr) => {
    console.log('total', total)
    console.log('currentValue', currentValue)
    console.log('currentIndex', currentIndex)
    console.log('arr', arr)
  // total 1
  // currentValue 2
  // currentIndex 1
  // arr [ 1, 2, 3, 4, 5 ]

  // total 3
  // currentValue 3
  // currentIndex 2
  // arr [ 1, 2, 3, 4, 5 ]

  // total 6
  // currentValue 4
  // currentIndex 3
  // arr [ 1, 2, 3, 4, 5 ]

  // total 10
  // currentValue 5
  // currentIndex 4
  // arr [ 1, 2, 3, 4, 5 ]
    return total + currentValue
})
console.log(result) // 15
let arr = [1, 2, 3, 4, 5]
let result = arr.reduce((total, currentValue, currentIndex, arr) => {
    console.log('total', total)
    console.log('currentValue', currentValue)
    console.log('currentIndex', currentIndex)
    console.log('arr', arr)
  // total 10
  // currentValue 1
  // currentIndex 0
  // arr [ 1, 2, 3, 4, 5 ]

  // total 11
  // currentValue 2
  // currentIndex 1
  // arr [ 1, 2, 3, 4, 5 ]

  // total 13
  // currentValue 3
  // currentIndex 2
  // arr [ 1, 2, 3, 4, 5 ]

  // total 16
  // currentValue 4
  // currentIndex 3
  // arr [ 1, 2, 3, 4, 5 ]

  // total 20
  // currentValue 5
  // currentIndex 4
  // arr [ 1, 2, 3, 4, 5 ]
    return total + currentValue
}, 10)
console.log(result) // 25

上面两个示例表示,如果没有设置初始值initialValue,那么第一次遍历时的total就是数组的第一项,函数会遍历执行 数组的长度 - 1 次。

如果有设置初始值initialValue,那么第一次遍历时的total就是初始值initialValue,函数会遍历执行 数组的长度 次。

如果有return 语句,第二次遍历时的 total 就是上一次return语句返回的值。如果没有return语句,total返回undefined(一般不会这样使用,都是有return语句的)

currentIndex是currentValue在数组中的下标值,arr是调用reduce()的数组

较为常用的就是前两个参数

2.  累加数组中对象的值

let arr = [
    { name: 'yee', num: 666 },
    { name: 'qian', num: 111 },
    { name: 'li', num: 111 },
]
let result = arr.reduce((prev, next) => {
    return prev + next.num
}, 0)
console.log(result) // 888

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

let arr = ['mysql', 'oracle', 'oracle', 'mysql', 'oracle', 'oracle', 'oceanbase', 'goldendb', 'db2', 'mongodb', 'gbase']
let result = arr.reduce(function (prev, next) {
    prev[next] = prev[next] + 1 || 1
    return prev
}, {})
console.log(result);
// { mysql: 2, oracle: 4, oceanbase: 1, goldendb: 1, db2: 1, mongodb: 1, gbase: 1 }

4. 数组去重

let arr = [1, 2, 3, 3, 2, 1, null, null, undefined, true, false, NaN, false, true, undefined]
let result = arr.reduce((prev, next) => {
    return prev.includes(next) ? prev : prev.concat(next)
}, [])
console.log(result); // [ 1, 2, 3, null, undefined, true, false, NaN ]

5. 对象数组的去重,相比于第4点,这种实际使用情况更多

// 根据对象的id值去重
let arr = [
    { id: 1, name: '张三' },
    { id: 2, name: '李四' },
    { id: 3, name: '王五' },
    { id: 1, name: '张三' },
]
let result = arr.reduce((prev, next) => {
    const isExist = prev.some((item) => item.id === next.id)
    if (!isExist) {
        prev.push(next)
    }
    return prev
}, [])
console.log(result)
// [ { id: 1, name: '张三' }, { id: 2, name: '李四' }, { id: 3, name: '王五' } ]

6. 将多维数组转为一维数组

// 二维
let arr = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
]
let result = arr.reduce((prev, next) => {
    return prev.concat(next)
}, [])
console.log(result)
// [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

// 多维
let arr1 = [1, [2, [[3, 4], 5], 6, 7, [8, 9, [10, 11, [12, 13]]]]]
function splitArr(arr) {
    return arr.reduce((prev, next) => {
        return prev.concat(Array.isArray(next) ? splitArr(next) : next)
    }, [])
}
console.log(splitArr(arr1)) 
// [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ]
console.log(arr1.flat(Infinity)) 
// [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ]
// 另:使用ES6中的flat()方法也可以实现
// flat(n): n非必填项,n默认是1,表示扁平化深度。Infinity表示不管嵌套多少层。

7. 将对象数组,按照对象的某个属性值进行分类

let animals = [
    { name: '小明', age: 6, type: 'dog' },
    { name: '小芳', age: 18, type: 'person' },
    { name: '小红', age: 6, type: 'cat' },
    { name: '小野', age: 18, type: 'person' },
    { name: '小雨', age: 6, type: 'dog' },
    { name: '小龙', age: 18, type: 'person' },
    { name: '滚滚', age: 8, type: 'dog' },
]

function classification(arr, attr) {
    if (!Array.isArray(arr)) {
        return []
    }
    return arr.reduce((prev, next) => {
        let obj = prev.find((item) => item.type == next.type)
        if (obj) {
            obj.list.push(next)
        } else {
            prev.push({
                [attr]: next[attr],
                list: [next],
            })
        }
        return prev
    }, [])
}
console.log(classification(animals, 'type'))
// [
//   {
//       "type": "dog",
//       "list": [
//           {
//               "name": "小明",
//               "age": 6,
//               "type": "dog"
//           },
//           {
//               "name": "小雨",
//               "age": 6,
//               "type": "dog"
//           },
//           {
//               "name": "滚滚",
//               "age": 8,
//               "type": "dog"
//           }
//       ]
//   },
//   {
//       "type": "person",
//       "list": [
//           {
//               "name": "小芳",
//               "age": 18,
//               "type": "person"
//           },
//           {
//               "name": "小野",
//               "age": 18,
//               "type": "person"
//           },
//           {
//               "name": "小龙",
//               "age": 18,
//               "type": "person"
//           }
//       ]
//   },
//   {
//       "type": "cat",
//       "list": [
//           {
//               "name": "小红",
//               "age": 6,
//               "type": "cat"
//           }
//       ]
//   }
// ]

除了上述场景,reduce() 方法还可以用于更复杂的数据处理和转换操作。它提供了一种灵活且强大的方式来处理数组中的元素,并生成最终的结果。根据具体的需求,你可以灵活运用 reduce() 方法来解决各种数组操作的问题。

 如果帮助到您了,可以留下一个赞👍告诉我  


文章作者: 程序猿小野
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 程序猿小野 !
评论