JavaScript

万金油reduce方法的使用场景

总结了数组中reduce()方法的使用场景

Yixuan Lang
2021-06-06
4 min

# 万金油reduce方法的使用场景

在有关整理数组方法的文章中提及到reduce()方法的使用,在数组方法中reduce()算是一个比较复杂的方法了。其功能也很强大,有很多的使用场景,算是一个万金油方法。这么好的方法怎么能不用起来呢,这篇文章我整理并总结了reduce()方法的多种使用场景,希望后期能灵活的将其运用在项目中。

reduce方法的使用场景

# 一、reduce()的用法

在正式了解reduce()方法的使用场景之前,先来回顾一下该方法的基本使用。我在网上找了一张图片我觉得可以十分贴切的描绘reduce()方法的作用~

image-20211008091039370

  • 作用:reduce()方法将数组的所有元素按照给定的方式计算为一个值(从左到右)
  • 传参:array.reduce(callback(accumulator, currentValue, currentIndex, arr), initialValue)
  • 参数说明:reduce()方法接收两个参数分别是:一个回调函数callback,和一个initialValue做为第一次调用callback函数时第一个参数的值,如果没有提供初始值则使用数组的第一个元素。在callback函数中包含四个参数
    • accumulator:累计器累计回调的返回值; 它是上一次调用回调时返回的累积值,如果没有给定initialValue参数时初始值是数组第一个值,后面会赋值为每次循环返回的值
    • currentValue:数组中正在处理的元素,没有给定initialValue参数时,初始值默认是数组第二个值,后面依次第三个...到最后一个
    • currentIndex:数组中正在处理的元素索引值
    • array:调用reduce()方法的原数组
  • 其内部的运行可以查看MDN官方文档,对reduce()方法的运行流程有详细的描述,这里就不赘述了

# 二、 使用场景

为了可以更好的展示如何在真实的开发场景中使用到reduce()方法,这里用一段开发中最常见的对象数组来对各个使用场景进行举例。

const members = [
    {id: '1', name: 'Mark', age: 20},
    {id: '2', name: 'Jane', age: 25},
    {id: '3', name: 'Wendy', age: 18},
    {id: '4', name: 'Alice', age: 20},
    {id: '5', name: 'Mino', age: 32},
    {id: '6', name: 'Sandy', age: 32},
]

# 1. 累加

需求:求所有成员的平均年龄

// 求得所有成员的总年龄
const ageSum = members.reduce((acc, cur) => acc + cur.age, 0)
const averageAge = ageSum / members.length
console.log(`平均年龄:${averageAge}`)   // 平均年龄:24.5

# 2. 最值

需求:求所有成员中年龄最大和最小值

function getMaxAge(arr) {
  const maxAgeMember =  arr.reduce((acc, cur) => acc.age > cur.age ? acc : cur)
  return maxAgeMember.age
}
console.log(`最大年龄:${getMaxAge(members)}`)   // 最大年龄:32

function getMinAge(arr) {
  const minAgeMember =  arr.reduce((acc, cur) => acc.age < cur.age ? acc : cur)
  return minAgeMember.age
}
console.log(`最小年龄:${getMinAge(members)}`)   // 最大年龄:18

# 3. 筛选

需求:获取年龄最大值的成员信息

// 上面已经定义了获取最大年龄的方法
const maxAge = getMaxAge(members)
function getMaxAgeMerber(arr, age) {
  return arr.reduce((acc, cur) => {
    if (cur.age === age) {
      acc.push(cur)
    }
    return acc
  }, [])
}
console.log('最大年龄成员: ', getMaxAgeMerber(members, maxAge))

image-20211009122332733

# 4. 判断

需求1:判断成员中有没有小于20岁的成员(替代了Array.prototype.some()方法)

const isLessThan20 = members.reduce((acc, cur) => acc || cur.age > 20, false)
console.log(`是否有小于20岁的成员:${isLessThan20}`)  // true

需求2:判断是不是所有的成员都大于18岁(替代了Array.prototype.every()方法)

const allMoreThan18 = members.reduce((acc, cur) => acc && cur.age > 18, true)
console.log(`是否所有成员大于18岁:${allMoreThan18}`)  // false

# 5. 数组转对象

需求:将members数组转换成以成员id为属性的对象结构

function arrToObj(arr, property) {
    return arr.reduce((acc, cur) => {
        const key = cur[property]
        acc[key] = cur
        return acc
    }, {})
}
console.log(arrToObj(members, 'id'))

image-20211009125116620

# 6. 出现次数

需求:统计成员中每个年龄的出现次数

const occurrences = members.reduce((acc, cur) => {
    let key = cur.age
    key in acc ? acc[key]++ : acc[key] = 1
    return acc
}, {})
console.log(occurrences)  // {18: 1, 20: 2, 25: 1, 32: 2}

# 7. 分类

需求:将成员按照不同年龄进行分类

const groupByAge = members.reduce((acc, cur) => {
    let key = cur.age
    if (!acc[key]) {
        acc[key] = []
    }
    acc[key].push(cur)
    return acc
}, {})
console.log(groupByAge)
// {
//     18: [{id: '3', name: 'Wendy', age: 18}],
//     20: [
//         {id: '1', name: 'Mark', age: 20},
//         {id: '4', name: 'Alice', age: 20}
//     ],
//     25: [{id: '2', name: 'Jane', age: 25}],
//     32: [
//         {id: '5', name: 'Mino', age: 32},
// 		{id: '6', name: 'Sandy', age: 32},
//     ]
// }  

# 三、其他使用场景

# 1. 数组扁平化

结合reduce()方法和递归操作,可以用于扁平化数组

function flatArr(arr) {
    return Array.isArray(arr) ? 
        arr.reduce((acc, cur) => [...acc, ...flatArr(cur)], []) : [arr]
}
const arr = [1, [2, [3, 4]]
console.log(flatArr(arr))   // [1, 2, 3, 4]

# 2. 数组去重

function unique(arr) {
    return arr.reduce((acc, cur) => acc.includes(cur) ? acc : [...acc, cur], [])
}
const arr = [1, 3, 5, 1, 9]
console.log(unique(arr))  // [1, 3, 5, 9]

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

function count(arr) {
    return arr.reduce((acc, cur) => {
        cur in acc ? acc[cur]++ : acc[cur] = 1
        return acc
    }, {})
}
const arr = ['apple', 'orange', 'apple', 'mango', 'mango']
console.log(count(arr))   // {apple: 2, orange: 1, mango: 2}

# 参考文章

js之reduce的最全用法

25个你不得不知道的数组reduce高级用法

自从学会了 Array.reduce() ,再也离不开它