一文搞懂ES6中数组reduce的用法

421 阅读2分钟

 序言

在js开发中,经常会对数组进行累加、展平、转换, 以便得到我们想要的数据。记得面试的时候面试官问过,使用过reduce嘛,当时一知半解的随口说了句一般累加的时候会用,觉得这个方法不好用,加上也不会用。后来了解之后,发现是真香啊。以下是关于reduce的一些常用使用方法。

 一、reduce的定义和语法

定义:reduce 是 JavaScript 中数组对象的一个方法,用于对数组中的每个元素执行一个提供的函数,并将其结果汇总为单一的输出值。这个方法可以用于数组的累加、拼接、过滤等多种操作。 注意: reduce() 对于空数组是不会执行回调函数的。

语法:

    array.reduce(function (total, currentValue, currentIndex, array) { }, initialValue)
    参数: total: 累加器,累计回调的返回值;它将在第一次调用时时initialValue(如何提供了),否则是数组的第一个元素
    currentValue:当前正在处理的元素。
    currentIndex(可选):当前正在处理的元素的索引。
    array(可选):调用 reduce 的数组。

三 、initialValue 参数的几种形式

initialValue(可选):作为第一次调用 callback 函数时第一个参数的值。如果没有提供,则使用数组的第一个元素。

1.initialValue省略

    const numbers = [1, 2, 3, 4, 5];
    const sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue);
    console.log(sum); // 输出: 15
 注意:如果数组为空而没有提供 initialValue,则会抛出一个错误

2. 使用对象作为 initialValue

可以将一个对象作为 initialValue,这在需要聚合数据时非常有用。

    const votes = [
        { candidate: 'Alice', count: 5 },
        { candidate: 'Bob', count: 3 },
        { candidate: 'Alice', count: 2 }
    ];
    const totalVotes = votes.reduce((accumulator, currentValue) => {
        if (!accumulator[currentValue.candidate]) {
            accumulator[currentValue.candidate] = 0;
        }
        accumulator[currentValue.candidate] += currentValue.count
        return accumulator
    }, {})
    console.log(totalVotes); // 输出: { Alice: 7, Bob: 3 }

3. 使用数组作为 initialValue

可以使用数组作为 initialValue,例如用于连接多个数组如用法3。

4. 使用数字作为 initialValue

可以使用一个数字作为 initialValue,通常用于计算总和或乘积等。

    const numbers = [1, 2, 3, 4, 5];
    const product = numbers.reduce((accumulator, currentValue) => accumulator * currentValue, 1);
    console.log(product); // 输出: 120

四、 reduce 常用的方法:

1.求和

    let arr = [
        {
            value: 10,
        },
        {
            value: 20,
        },
        {
            value: 20,
        },
    ];
    let newArr = arr.reduce((acc, cur) => {
        return acc + cur.value;
    }, 0);
    console.log(newArr);   //50

2.计算数组元素次数

    const nameList = ['xiaomi', 'huawei', 'pingguo', 'xiaomi', 'huawei', 'huawei']

    const filterItem = nameList.reduce((pre, item) => {
        if (item in pre) {
            pre[item]++
        } else {
            pre[item] = 1
        }
        return pre

    }, {})
    console.log(filterItem)

3.多维数组展平

    let arr = [[0, 1], [2, 3], [4, [5, 6, 7]]]
    const flattenArray = (arr) => {
        return arr.reduce((pre, item) => {
            if (Array.isArray(item)) {
                return pre.concat(flattenArray(item))
            }
            return pre.concat(item)
        }, [])

    }
    const result = flattenArray(arr)
    console.log(result)// 输出: [0, 1, 2, 3, 4, 5, 6, 7]

4.数组去重

    let arr = [3, 9, 4, 3, 6, 0, 9];
    const result = arr.reduce((pre, item) => {
        if (pre.indexOf(item) == -1) {
            pre.push(item)
        }
        return pre
    }, [])
    console.log(result)// [3, 9, 4, 6, 0]