reduce()基本概念

reduce() 方法为数组中的每一个元素依次执行回调函数(不包括数组中被删除或从未被赋值的元素),返回一个具体的结果。

语法

reduce() 接收两个参数,其基本语法为:

arr.reduce(callback,[initialValue])
arr. reduce( function(previousValue, currentValue, index,array){
}, initialValue);
//或者
arr. reduce( function(previousValue, currentValue, index,array){
},);

参数解析:
callback 执行数组中每个值的函数,包含四个参数:

previousValue    第一项的值或者上一次叠加的结果值,或者是提供的初始值(initialValue)
currentValue    数组中当前被处理的元素
index     当前元素在数组中的索引
array     数组本身

initialValue (可选) 作为第一次调用 callback 的第一个参数,可以控制返回值的格式
常用的就是previousValuecurrentValue

例子

从initialValue 传与不传的区别

const arr = [2, 4, 6, 8, 10];
let i = 0;
arr.reduce((pre, cur, index, arr) => {
    console.log(`第${ i + 1 }次执行:pre:${ pre },cur:${ cur },index:${ index }`);
    i++;
    return pre + cur;
}, 10);

// 第1次执行:pre: 10, cur: 2, index: 0
// 第2次执行:pre: 12, cur: 4, index: 1
// 第3次执行:pre: 16, cur: 6, index: 2
// 第4次执行:pre: 22, cur: 8, index: 3
// 第5次执行:pre: 30, cur: 10, index: 4
// 40

代码分析:

  1. 数组中的元素依次执行了回调函数。
  2. 因为给 initialValue 赋了初始值 10,所以第一次执行时, pre 的值默认从 10开始。
  3. 每次执行时,pre 的值都是 cur 元素前的所有元素之和。
  4. 最后返回数组所有元素累加的和

我们再看一下不传 initialValue 参数的执行结果:

const arr = [2, 4, 6, 8, 10];
let i = 0;
arr.reduce((pre, cur, index, arr) => {
    console.log(`第${ i + 1 }次执行:pre:${ pre },cur:${ cur },index:${ index }`);
    i++;
    return pre + cur;
});

// 第1次执行:pre: 2, cur: 4, index: 1
// 22 第2次执行:pre: 6, cur: 6, index: 2
// 22 第3次执行:pre: 12, cur: 8, index: 3
// 22 第4次执行:pre: 20, cur: 10, index: 4
// 30

可以看到,这里只执行了四次,且是从数组的第二位开始执行的,数组的第一位默认作为了 pre 的值。

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

const arr = ['name', 'age', 'long', 'short', 'long', 'name', 'name']

arr.reduce((pre, cur) => {
    console.log(pre, cur)
    if (cur in pre) {
        pre[cur]++
    } else {
        pre[cur] = 1
    }
    return pre
}, {})


// { } "name"
// {name: 1} "age"
// {name: 1, age: 1} "long"
// {name: 1, age: 1, long: 1} "short"
// {name: 1, age: 1, long: 1, short: 1} "long"
// {name: 1, age: 1, long: 2, short: 1} "name"
// {name: 2, age: 1, long: 2, short: 1} "name"
// {name: 3, age: 1, long: 2, short: 1}

数组去重

const arr = ['name', 'age', 'long', 'short', 'long', 'name', 'name'];

let arrResult = arr.reduce((pre, cur) => {
    if (!pre.includes(cur)) {
        pre.push(cur)
    }
    return pre;
}, [])

// ["name", "age", "long", "short"]

将多维数组转化成一维数组

const arr = [1, 2, 2, 3, [9, 8, 7,[5, 2, 1]]]
const flatten = arr => {
    return arr.reduce(
        (pre, cur) => {
            return pre.concat(Array.isArray(cur) ? flatten(cur) : cur);
        }, [])
}
const res4 = flatten(arr)
console.log(res4)

// Array.isArray() 用于确定传递的值是否是一个 Array
//[1, 2, 2, 3, 9, 8, 7, 5, 2, 1]