数组处理的神兵利器-reduce

前言

reduce,这个高级函数,大家最开始应该是用于求和。我也是,仅仅在求和中遇到它。后来数组越来越复杂,想查找简单解决办法的时候发现了这个大杀器的更多使用。现在,它成为了我最爱的高阶函数,没有之一。reduce参数说明我就不多介绍了,下面主要是一些实战小技巧。

1
[1,2,3].reduce((c,n)=>c+n);

替代部分其他数组高阶函数

  1. reduce替代map

    1
    2
    3
    const arr = [{name:'Amy'},{name:'Bob'}];
    arr.map(it=>it.name); // map
    arr.reduce((c,n)=>[...c,n.name],[]); // reduce
  2. reduce替代filter

    1
    2
    3
    const arr = [{name:'Amy',age:18},{name:'Bob',age:20}];
    arr.filter(it=>it.age>18); // filter
    arr.reduce((c,n)=>n.age>18? [...c,n]:c,[]); // reduce
  3. reduce替代 map + filter。

    1
    2
    3
    const arr = [{name:'Amy',age:18},{name:'Bob',age:20}];
    arr.filter(it=>it.age>18).map(it=>it.name); // 多重循环效率低浪费大
    arr.reduce((c,n)=>n.age>18? [...c,n.name]:c,[]); // reduce Bob
  4. reduce替代some或者every

    1
    2
    3
    const arr = [{name:'Amy',age:18},{name:'Bob',age:20}];
    arr.reduce((c,n)=>c||n.age>18 , false); // some
    arr.reduce((c,n)=>c&&n.age>18 , true); // every

暂时介绍这么多,其余的请自己去发现发掘。

串行执行promise

最典型的,就是大文件分片上传。串行上传分片可以保证上传分片数的数据并且可以自己模拟出上传进度。常规处理就是采用递归,速度很快,但是还不够优雅。reduce使这个操作的优雅程度更上一层楼。大概用法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    // 定义或者求得chunks代表存有文件分片的数组
chunks.reduce((c,n)=>c.then(res=>{
// 处理某个分片上传成功后的处理
return axios.post(...)
}),Promise.resolve())
```
## 解题有奇效
前端群里,或者掘金沸点里头,或多或少会有问一下奇怪的数组问题。我这边基本都采用reduce进行处理帮忙解答一下。比如:

1. [1,2,3] => [1,1,2,2,3,3]
常规做法应该是创建新的空数组,然后老数组循环赋值给原空数组。reduce就一行。
```javascript
[1,2,3].reduce((c,n)=>[...c,n,n],[]);
// 或者
[1,2,3].reduce((c,n)=>[...c,...new Array(num).fill(n)],[]);//利用num控制数量
```
2. [1,2,3,4] => \[[1,2],[3,4]]
常规做法还是创建新数组,然后循环判断。reduce依然是一行
```javascript
[1,2,3,4].reduce((c,n)=>{c[c.length-1].length>=2?c.push([n]):c[c.length-1].push(n);return c},[[]])

总结

其实前端行业有一些人是api调用工程师,会vue/react,然后就不管自己的一些算法是否优秀,是否可以继续改进。往往造成的就是效率低还代码里冗余。不沉迷,不妄自菲薄,学好基础,你会是那颗金子的,就像reduce一样。


作者简介: 张栓,人和未来大数据前端工程师,专注于html/css/js的学习与开发。