文章目录
前言
写在前面,在写这篇文章之前,我一直不能理解reduce()的用法,实际项目中也很少用到。直到有一天,我下定决心想要好好学习reduce()方法的使用,是因为我刷到了这样一道题…
问题:给定一个不重复集合,编写代码,能够输出其所有子集合。例如对于输入集合[1,2,3],返回以下集合,顺序不限:
[
[], [ 1 ],
[ 2 ], [ 2, 1 ],
[ 3 ], [ 3, 1 ],
[ 3, 2 ], [ 3, 2, 1 ]
]
答案:
const test = arr => (
arr.reduce((prev, next) => [
...prev,
...prev.map(item => [
next,
...item
])
], [[]])
)
console.log(test([1,2,3]));
看不懂reduce的我,一脸懵逼
于是打开菜鸟教程,它的介绍是下面这样的:
一、语法
1.定义和用法
- reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
- reduce() 可以作为一个高阶函数,用于函数的 compose。
- 注意: reduce() 对于空数组是不会执行回调函数的。
2.语法
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
3.参数
看上去是不是感觉很复杂?其实常用的参数只有前两个:total 和 currentValue,下面跟着大量的实例来掌握它~
二、实例
1.计算数组元素相加后的总和(官网例子)
var arr = [1, 2, 3, 4, 5]
var sum = arr.reduce((total, cur) => {
console.log(total, cur)
return total + cur
}, 10)
console.log('总和:', sum) // 25
打印出来看看total和cur到底是什么东东:
可以看到,以上回调被调用了5次,由于传入了初始值10,所以开始时total的值为10,cur的值为数组第一项1,相加之后返回值为11作为下一轮回调的total值,然后再继续与下一个数组项2相加,以此类推,直至完成所有数组项的和并返回,也就是完成了 10 + 1 + 2 + 3 + 4 + 5 的计算。
如果初始值不传:
var arr = [1, 2, 3, 4, 5]
var sum = arr.reduce((total, cur) => {
console.log(total, cur)
return total + cur
})
console.log('总和:', sum) // 15
打印结果如下:
以上回调被调用了4次,开始时total的值为数组的第一项。
2.求数组项最大值
var arr = [1, 2, 3, 4, 5]
var sum = arr.reduce((total, cur) => {
return total>cur ? total : cur
})
console.log('最大值:', sum) // 5
3.计算一个字符串中每个字母出现次数
var str = 'jshdjsihh';
var obj = str.split('').reduce((total, cur) => {
total[cur] ? total[cur] ++ : total[cur] = 1
return total
},{})
console.log(obj) // {j: 2, s: 2, h: 3, d: 1, i: 1}
4.数组去重/对象数组去重
var arr = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
var sum = arr.reduce((total, cur) => {
total.indexOf(cur) == -1 && total.push(cur)
return total
}, [])
console.log(sum) // [1, 2, 3, 4, 5]
var arr = [
{id:'1'},
{id:'2'},
{id:'3'},
{id:'1'},
{id:'2'},
{id:'3'},
];
var obj = {};
var sum = arr.reduce((total, cur) => {
obj[cur.id] ? "" : obj[cur.id] = true && total.push(cur)
return total
}, [])
console.log(sum) // [{id: "1"},{id: "2"},{id: "3"}]
5.扁平一个二维数组
var arr = [[1, 2, 8], [3, 4, 9], [5, 6, 10]];
var sum = arr.reduce((x, y) => x.concat(y), []);
console.log(sum) // [1, 2, 8, 3, 4, 9, 5, 6, 10]
6.递归利用reduce处理tree树形
var data = [{
id: 1,
name: "办公管理",
pid: 0,
children: [{
id: 2,
name: "请假申请",
pid: 1,
children: [
{ id: 4, name: "请假记录", pid: 2 },
],
},
{
id: 3,
name: "出差申请",
pid: 1
}]
},
{
id: 5,
name: "系统设置",
pid: 0,
children: [{
id: 6,
name: "权限管理",
pid: 5,
children: [
{ id: 7, name: "用户角色", pid: 6 },
{ id: 8, name: "菜单设置", pid: 6 },
]
}]
}];
const arr = data.reduce(function(total, cur){
const callee = arguments.callee //将运行函数赋值给一个变量备用
total.push(cur)
if(cur.children && cur.children.length > 0) cur.children.reduce(callee, total); //判断当前参数中是否存在children,有则递归处理
return total;
},[]).map((cur) => {
cur.children = []
return cur
})
console.log(arr)
打印结果:
三、其他相关方法
1.reduceRight()
该方法用法与reduce()其实是相同的,只是遍历的顺序相反,它是从数组的最后一项开始,向前遍历到第一项。
var arr = [1, 2, 3, 4, 5]
var sum = arr.reduceRight((total, cur) => {
console.log(total, cur)
return total + cur
},10)
console.log(sum) // 25
打印结果:
2.forEach()、map()、filter()、every()、some()
详情请点击:简述forEach()、map()、filter()、every()、some()的用法
总结
reduce() 是数组的归并方法,与forEach()、map()、filter()等迭代方法一样都会对数组每一项进行遍历,但是reduce() 可同时将前面数组项遍历产生的结果与当前遍历项进行运算,这一点是其他迭代方法无法企及的。
参考
https://www.runoob.com/jsref/jsref-reduce.html
https://www.cnblogs.com/amujoe/p/11376940.html
https://www.cnblogs.com/smallpen/p/10249288.html