日常工作中对数组中的 API 使用频率还是挺高的,唯独 reduce(),在阅读相关介绍时,一直很难理解,只记得数组求和和去重,能够用到它,其他地方怎么用,就无法灵活变通了。今天索性来认真地总结一下reduce()的用法,学会在更多的地方使用它,提升代码水平和开发效率。
一、基本语法
1  | arr.reduce(function(prev,cur,index,arr){...},init);  | 
其中参数从左到右依次是prev、cur、index、arr、init。
| 参数 | 含义 | 必需 | 
|---|---|---|
prev | 上一次调用回调时的返回值,或者初始值init | 是 | 
cur | 当前正在处理的数组元素 | 是 | 
index | 当前正在处理的数组元素的索引,若提供 init 值,则index从0开始,否则索引从1 开始 | 可选 | 
arr | 原数组 | 可选 | 
init | 初始值 | 可选 | 
5个参数看上去十分复杂,然则真正常用的参数只有两个即prev 和cur,可以通过具体示例来学习一下如何使用它。
二、常用示例
首先提供一个元素都是Number类型的原始数组:const origin = [1,2,3,4,5]
1、求该数组各项之和
1  | const arr_one = [1,2,3,4,5];  | 
分析:由于传入了初始值0,所以开始时 prev = 0,cur 是数组第1项 1,相加(0+1)后的返回值为 1 作为下一轮回调的 prev 的值,即 prev = 1,然后在继续与下一个数组项 cur = 2 相加,以此类推,直到完成所有数组项的和并返回。
prev = init = 0, cur = arr[0] = 1, index=0, prev + cur = 1;
prev = 1,cur = 2,index = 1, prev + cur = 3; prev = 3,cur = 3,index = 2, prev + cur = 6;
prev = 6,cur = 4,index = 3, prev + cur = 10; prev = 10,cur = 5,index = 4,prev + cur = 15;
2、求数组项的最大值
1  | const arr_two = [6,4,2,3,4,5];  | 
由于未传入初始值 init,prev 为数组第1项6,cur 为数组第2项1,取两个值的最大值后继续进行下一轮回调。
3、数组进行去重操作
1  | const arr_three = [7,8,5,4,4,5,6,7,8];  | 
基本实现原理:
(1)、初始化一个空数组即 prev = init = []
(2)、将需要做去重处理的数组中的第1项在初始化数组中查找,找不到(空数组中肯定找不到),添加到初始数组 prev 中
(3)、将需要做去重处理的数组中的第2项在初始化数组中查找,找不到(空数组中肯定找不到),添加到初始数组 prev 中
(4)、以此类推,…
(5)、将需要做去重处理的数组中的第n项在初始化数组中查找,找不到(空数组中肯定找不到),添加到初始数组 prev 中
(6)、最后返回初始化数组即 prev
三、其他用法
1.reduceRight()
该方法用法与reduce() 相同,只是遍历的顺序相反,它是从数组的最后一项开始,向前遍历到第1项。
2.forEach()、map() 、every()、 some()和 filter()
reduce() 是数组的归并方法,与forEach()、map()、filter()等迭代方法一样都会对数组的每一项进行遍历,只是
reduce()可同时将前面数组项遍历产生的结果与当前遍历项进行运算,这是其他迭代方法所不具备的特性。
四.进阶用法
(1) 数组对象中的用法
需求1:生成 “老大、老二和老三”
1  | const objArr = [{name:"老大"},{name:"老二"},{name:"老三"}];  | 
(2) 字符串中字母出现次数
需求2:求字符串中字母出现次数
1  | const str = 'sfhjasfjgfasjuwqrqadqeiqsajsdaiwqdaklldflas-cmxzmnha';  | 
(3) 数组转数组
需求3:按照一定的规则转成数组,例如:每个值的平方
1  | const arr_origin = [1,2,3,4,5];  | 
(4) 数组转对象
需求4:按照id 取出 stream
1  | const streams = [{name:'tech',id:1},{name:'design',id:2},{name:'math',id:3}];  | 
五、高阶用法
(1)多维叠加执行操作
需求1:各科成绩占比重不一样,求结果
1  | const result = [  | 
需求2:商品对应不同国家汇率不同,求总价格
1  | const prices = [{price:23}, {price:45}, {price:56}];  | 
(2)扁平一个数组
1  | const arr = [[1, 2], [8], [3, 4, 9], [5, 6, 10]];  | 
(3)对象数组去重
1  | const hash = {};  | 
(4) redux compose 源码实现
1  | function compose(...funs) {  |