JavaScript中reduce()方法详解

发布时间:2023-05-12浏览次数:364 次
reduce()方法是JavaScript中很强大的一个方法,很多前端小伙伴都知道这个方法可以用来做数组求和,数组求积等需求,但是对reduce()方法的执行原

reduce()方法是JavaScript中很强大的一个方法,很多前端小伙伴都知道这个方法可以用来做数组求和,数组求积等需求,但是对reduce()方法的执行原理却不清楚。这里我们就详细的剖析下JavaScript中reduce()方法的使用,先以数组求和为例,要实现数组求和,在以前,我们需要可能会使用如下的方法来实现:

let ary = [1, 2, 3, 4],
    sum = 0;
ary.forEach((item, index) => sum += item)
console.log(sum);

即,我们要先定义一个用来接收最终和的变量,并对其赋初始值0,然后对数组的每一项进行累加。相信这种实现方法大家都能看的懂。接下来我们讲解如何使用reduce()方法来实现数组求和。

reduce()方法,默认接收两个参数,其中第一个参数为一个函数,第二个参数为初始值,为可选参数。其中第一个参数(函数)可接收四个参数,分别为:前一个值、当前项、项目的索引和数组对象。

语法如下:

ary.reduce((prev,cur,index,arr)=>{},init);

参数说明:

  1. prev 必需。累计器累计回调的返回值; 表示上一次调用回调时的返回值,或者初始值 init;
  2. cur 必需。表示当前正在处理的数组元素; 
  3. index 可选。表示当前正在处理的数组元素的索引,若提供 init 值,则起始索引为- 0,否则起始索引为1; 
  4. arr 可选。表示原数组; init 可选。表示初始值

为了更好的演示说明,接下来我们分两种情况分别讨论:

一、填写第二个参数:

ary.reduce((prev,cur)=>{
    console.log(prev,cur)
},0);

打印结果如下:

0 1
undefined 2
undefined 3
undefined 4

从第二次循环开始,prev变成了undefined,我们在函数中添加return语句,

ary.reduce((prev,cur)=>{
    console.log(prev,cur);
    return 6;
},0);

则打印结果变为:

0 1
6 2
6 3
6 4

到这一步,我们可以理解,从数组的第二次循环开始,prev的值,来源于方法上次的返回结果值。接下来,我们再改变init初始值为8,进行测试:

ary.reduce((prev,cur)=>{
    console.log(prev,cur);
    return 6;
},8);

打印结果如下:

8 1
6 2
6 3
6 4

到这一步,相信我们可以从中找到规律了,即在传有init参数时,prev在第一次循环时,其值来源于init设置的初始值,从第二次循环开始,其值来源于上一次循环返回的结果值。那么找到这个规律,我们就可以很好的实现,数组求和了:

let sum = ary.reduce((prev, cur) => {
    return prev + cur;
}, 0);
console.log(sum);

二、省略第二个参数:

接下来我们尝试省略第二个参数:

ary.reduce((prev, cur) => {
    console.log(prev, cur);
});

打印结果如下:

1 2
undefined 3
undefined 4

发现数组只循环了三次,我们改变原数组,再试一次:

let ary = [8, 9, 3, 4];

ary.reduce((prev, cur) => {
    console.log(prev, cur);
});

则打印结果如下:

8 9
undefined 3
undefined 4

这里我们已经可以猜测到大致的规律了,即在不传init初始值的情况下,reduce()方法,默认从第二项开始循环,prev的值为数组第一个值,cur为数组第二个值。

理解到这里,再去对照官方的说明文档,我们就能很容易理解了。需要着重记忆的点是:

1、reduce传入第二个参数,则数组从第一项开始循环,第一次的prev值为第二个参数值。

2、reduce省略第二个参数,则数组从第二项开始循环,第一次的prev值为数组的第一项。

接下来,我们再用图示的形式加强巩固下:

理解了reduce()方法的使用,我们再来看几个需求:

三、练习

3.1 数组求积

let ary = [1, 2, 3];
let multiply = ary.reduce((prev,cur)=>{
    return prev * cur;
})
console.log(multiply);  // 6

3.2 统计数组中,各元素出现的次数

let ary = ['apple','b','apple','b','orange','apple','red'];
let res = ary.reduce((prev,cur)=>{
    if (!prev[cur]){
        prev[cur] = 1;
    }else{
        prev[cur] += 1;
    }
    return prev;
},[])
console.log(res);

执行代码,返回结果为:

[ apple: 3, b: 2, orange: 1, red: 1 ]

当然,这里的init参数,我们不仅可以设置为空数组,也可以设置为空对象。需要注意的是,在数组第一次循环时,prev的初始值为设置的init参数(空数组或空对象)。

3.3 数组去重

let ary = ['apple', 'b', 'apple', 'b', 'orange', 'apple', 'red'];
let res = ary.reduce((prev, cur) => {
    if (prev.indexOf(cur) === -1) prev.push(cur);
    return prev;
}, [])
console.log(res);

3.4 数组求最大项

let ary = [1, 2, 0, 5, 8, 9, 1];
let max = ary.reduce((p, c) => {
    return Math.max(p, c);
})
console.log(max);

这里需要注意,在实际项目中,我们需要确认数组的每个元素都是纯数字,否则,要进行判断。

扫一扫,在手机上查看