前言
最近和同事 A 聊天聊到
es6
一些基础知识,在问到reduce
时,同事给我的回答是:‘不就是用来求和的吗’ ???‘你确定 ???’应该有不少童鞋肯定也是这样认为的吧,因为在一般基础性的教程中,举例最多的就是数组求和。其实
reduce
还要很多妙用。下面我们就来看看神奇的reduce
介绍
reduce()方法可以搞定的东西,for 循环,或者 forEach 方法有时候也可以搞定,那为啥要用 reduce()?这个问题,之前我也想过,要说原因还真找不到,唯一能找到的是:通往成功的道路有很多,但是总有一条路是最捷径的,亦或许 reduce()逼格更高...
reduce 语法
arr.reduce(callback,[initialValue])
callback 详解
reduce 为数组中的每一个元素依次执行回调函数callback
,不包括数组中被删除或从未被赋值的元素,接受四个参数
:
- 初始值(或者上一次回调函数的返回值)
- 当前元素值
- 当前索引
- 调用 reduce 的数组。
initialValue(可选参数)
当设置了initialValue
参数时,callback
第一个参数 初始值
将默认是 initialValue
。
先看一个例子:
var arr = [1, 2, 3, 4]; var sum = arr.reduce(function(prev, cur, index, arr) { console.log(prev, cur, index); return prev + cur; }) console.log(arr, sum);
打印结果:这是一个最经典的数组求和
的例子,也是reduce
最简单使用,这个例子index
是从0
开始的,第一次的prev
的值是我们设置的初始值0
,数组长度是 4,reduce 函数循环4次
。
注意:如果这个数组为空,运用 reduce 是什么情况?
var arr = []; var sum = arr.reduce(function(prev, cur, index, arr) { console.log(prev, cur, index); return prev + cur; })
但是要是我们设置了初始值就不会报错,如下:
var arr = []; var sum = arr.reduce(function(prev, cur, index, arr) { console.log(prev, cur, index); return prev + cur; },0) console.log(arr, sum);
reduce 简单用法
- 数组求和,求乘积
var arr = [1, 2, 3, 4]; var sum = arr.reduce((x,y)=>x+y) var mul = arr.reduce((x,y)=>x*y) console.log( sum ); //求和,10 console.log( mul ); //求乘积,24
- 求数组项最大值
var arr = [1, 2, 3, 4]; var max = arr.reduce(function (prev, cur) { return Math.max(prev,cur); }); console.log(max) // 4
- 数组去重
var arr = [1, 2, 3, 4, 5, 4, 3, 2, 1]; var newArr = arr.reduce(function (prev, cur) { prev.indexOf(cur) === -1 && prev.push(cur); return prev; },[]); console.log(newArr) // [1, 2, 3, 4, 5]
reduce 高级用法
- 计算数组中每个元素出现的次数
let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice']; let nameNum = names.reduce((pre,cur)=>{ if(cur in pre){ pre[cur]++ }else{ pre[cur] = 1 } return pre },{}) console.log(nameNum); //{Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}
- 将二维数组转化为一维
let arr = [[0, 1], [2, 3], [4, 5]] let newArr = arr.reduce((pre,cur)=>{ return pre.concat(cur) },[]) console.log(newArr); // [0, 1, 2, 3, 4, 5]
- 将多维数组转化为一维
let arr = [[0, 1], [2, 3], [4,[5,6,7]]] const newArr = function(arr){ return arr.reduce((pre,cur)=>pre.concat(Array.isArray(cur)?newArr(cur):cur),[]) } console.log(newArr(arr)); //[0, 1, 2, 3, 4, 5, 6, 7]
- 对象数组去重
let data = [{ name: 'tom', id: 1 }, { name: 'jack', id: 2 }, { name: 'sam', id: 3 }, { name: 'mike', id: 1 }, { name: 'amy', id: 2 }, { name: 'eric', id: 3 } ] let hash = {} data = data.reduce((item, next) => { // 根据 id 去重 if (!hash[next.id]) { hash[next.id] = true item.push(next) } return item }, []) console.log(hash) // {1: true, 2: true, 3: true} console.log(data)
compose
函数
什么是
compose
函数 ?不了解的话可以看看掘金大佬的一篇文章:https://juejin.cn/post/6989020415444123662
function compose(...funs) { if (funs.length === 0) { return arg => arg; } if (funs.length === 1) { return funs[0]; } return funs.reduce((a, b) => (...arg) => a(b(...arg))) }
其它相关方法
reduceRight()
该方法用法与reduce()其实是相同的,只是遍历的顺序相反,它是从数组的最后一项开始,向前遍历到第一项。