简介
- rudece这个方法和迭代方法(map,forEach,filter…)一样,都会对数组进行遍历,reduce与他们不同的是函数的第一个参数得到的是迭代计算后的效果(看不懂没关系,继续往下看就会懂了)
语法
-
这个方法主要接收两个参数
1. 要执行的函数,要执行的函数中也可传入参数,分别为(pre,cur,index,arr)pre:上次调用函数的返回值 cur:本次操作的元素 index: 本次操作元素的下标 arr: 原数组
- 函数迭代的初始值(可以不写,非必填)
实例
- 不写第二个参数
let arr = [1, 2, 3, 4];
let sum = arr.reduce((pre, cur, index, arr) => {
console.log(pre, cur, index); // pre 初始为 1 cur初始为 2
return pre + cur; // 返回结果为下次的pre值
})
console.log(arr, sum); // [1,2,3,4] 10
//一个简单的累加器,不会改变原数组
-
运行结果
-
我们可以看到,在这里reduce的作用就是对这个数组进行求和,迭代了3次,函数迭代的初始值是1,也就是默认值(数组的第一项),pre的值是每次计算后的值。
-
设置初始迭代值
let arr = [1, 2, 3, 4];
let sum = arr.reduce((pre, cur, index, arr) => {
console.log(pre, cur, index); // 如果设置初始值的话 cur 的初始值为数组的第0项 即为1
return pre + cur;
},5) // 第二参数为pre的初始值
console.log(arr, sum);
-
运算结果
-
高级运用
- 计算数组中每个元素出现的次数
- 现在有数组
let arr = ['apple','banana','pear','apple','apple','pear','banana','peach']
const arrResult = arr.reduce((pre,cur,index) => {
// console.log(pre,cur,index) ;
if( pre[cur] === undefined ) {
pre[cur] = 1 ;
} else {
pre[cur]++
}
return pre
},{}) //初始化pre为{}
for(var prop in arrResult) {
console.log(prop,arrResult[prop])
}
- 运行结果
分析分析:
大概的解释一下,运行过程是这样的:
1.由于设置了迭代初始值,pre的第一个值是一个空对象,此时cur为apple,然后进行判断,发现在pre中没有
apple属性,所以就将name对应的属性值赋为1;
2.后面没有重复的是一样的道理,如果碰到重复值,就会将该属性值加1,这样就能计算元素重复的次数了。
(有没有觉得很神奇呀~)
- 同样可以利用reduce进行去重数组
const arrResult = arr.reduce((pre,cur,index) => {
console.log(pre,cur,index) ;
if( !pre.includes(cur) ) {
pre.push(cur);
}
return pre
},[])
console.log(arrResult);
-
运行结果
-
分析
-
是不是使用reduce进行去重贼简单。只要你掌握reduce原理后,发现一些对数组进行操作得到想要的结果,运用reduce来实现,特别容易,代码不冗余,且易懂。 甚至可以万物皆可reduce
-
万物皆可 reduce
-
reduce方法是真的越用越香,其他类型的值也可转为数组后使用reduce:
-
字符串:[…str].reduce()
-
数字:Array.from({ length: num }).reduce()
-
对象:
Object.keys(obj).reduce() Object.values(obj).reduce() Object.entries(obj).reduce()
-
-
最后在写个在实际开发需要实现的功能
-
原数组
let arr = [
{ name: 'book', number: 10 },
{ name: 'paper', number: 10 },
{ name: 'ruber', number: 10 },
{ name: 'book', number: 20 },
{ name: 'paper', number: 40 },
{ name: 'ruber', number: 50 },
{ name: 'book', number: 70 },
{ name: 'paper', number: 80 },
{ name: 'ruber', number: 90 },
];
- 需要转换为 (目标数组)
let newArr = [
{ name: 'book', value: [10, 20, 70] },
{ name: 'ruber', value: [10, 40, 80] },
{ name: 'paper', value: [10, 50, 90] },
];
-看似乎很困难,但是使用reduce 发现真的十分容易
- 直接上代码
const ret = arr.reduce((pre,cur,index,item)=>{
// console.log(pre,cur,index);
if(pre[cur.name] === undefined) {
pre[cur.name] = {
name : cur.name ,
value : [cur.number]
}
}
else {
pre[cur.name].value.push(cur.number);
}
return pre ;
},{})
// console.log(ret);
console.log(Object.values(ret)) // 结果即为目标数组