首先,参考了这位大佬的总结,敲了一遍,收获很大。记录下来。跳转
背景:
之前是接触vue源码的时候,发现使用reduce的地方很多。当时也是在看别人分享,简单带过,发现很好用。简单研究后,很少用到。导致理解不深。今天碰到到使用场景,特意花时间研究了一番,可以说理解的很到位了。
语法
arr.reduce(function(prev,cur,index,arr){
...
}, init);
其中,
arr 表示原数组;
prev 表示上一次调用回调时的返回值,或者初始值 init;
cur 表示当前正在处理的数组元素;
index 表示当前正在处理的数组元素的索引,若提供 init 值,则索引为0,否则索引为1;
init 表示初始值。【这个初始值在很多技巧上要用到,要重点留意】
在实际使用当中,其实常用的参数只有两个:prev 和 cur。结合例子来分析一番。
实例
以下举的例子除了用reduce来实现,还有很多其他的方法。不过使用reduce有它独有的技巧性和方便。
1、求数组的和
方式一:
let arr = [3,4,5,6,9,2,4,6];
let sum = arr.reduce((pre,cur,index,arr)=>{
// console.log('index:',index);
// console.log('arr:',arr);
return pre + cur;
})
console.log(sum);
方式二:
let sum = arr.reduce((pre,cur,index,arr)=>{
// console.log('index:',index);
// console.log('arr:',arr);
return pre + cur;
},0)
console.log(sum);
注意:方式二,由于传入了初始值0,所以pre的初始值就是0,cur的值,就是数组的第一个值为3;如果不传初始值的话,就如方式一,这时,pre的值是3,cur的值是4;相加后为7,作为下一轮的pre的值,cur是5,依次类推下去。
2、求数组的最大值
方式一:
let arr = [1,4,5,6,9,2,4,6];
let max = arr.reduce((pre,cur)=>{
return Math.max(pre,cur)
})
console.log(max);
方式二:
let max2 = arr.reduce((pre,cur)=>{
return pre > cur ? pre:cur;
})
console.log('max2:',max2);
3、给数组去重
let newArr = arr.reduce((pre,cur)=>{
pre.indexOf(cur) === -1 && pre.push(cur)
return pre
},[])
console.log(newArr);
进阶用法
1.求字符串中字幕出现的次数
const str = 'sfhjasfjgfasjuwqrqadqeiqsajsdaiwqdaklldflas-cmxzmnha';
const res = str.split('').reduce((pre,cur)=>{
pre[cur] ? pre[cur]++ : pre[cur] = 1;
return pre
},{})
console.log('汇总次数:',res);
2.数组转数组
let arr1 = [2,3,4,5,6,7];
let newArr1 = arr1.reduce((pre,cur)=>{
pre.push(cur*cur)
return pre;
},[])
console.log('数组转数组:',newArr1);
3. 数组转对象
let streams = [{ name: '博士',id: 1},{ name:'硕士', id:2},{ name: '本科',id:3}];
let obj1 = streams.reduce((pre,cur)=>{
pre[cur.id] = cur;
return pre;
},{})
console.log('数组转对象:',obj1);
高级用法
1. 多维的叠加执行操作
例子:各科成绩占比不一样,求结果
const result = [
{ subject: 'math',score: 99},
{ subject: 'chinese',score:95},
{ subject: 'english',score:80},
];
const dis = {
math: 0.5,
chinese: 0.2,
english: 0.4
};
let res2 = result.reduce((pre,cur)=>{
return dis[cur.subject] * cur.score + pre
},0)
console.log('多维叠加:',res2);
加大难度:商品对应不同国家汇率不同,求价格
const prices = [{price: 23},{price: 45},{price:56}];
const rates = { us: '6.5', eu:'7.5'};
const initialState = { usTotal: 0, euTotal: 0};
const res3 = prices.reduce((pre1,cur1)=> Object.keys(rates).reduce((pre2,cur2)=>{
pre1[`${cur2}Total`] += cur1.price * rates[cur2];
return pre1;
},{}),initialState)
console.log(res3);
2、扁平一个二维数组
const arr4 = [ [1,2,3],[4,5,6],[7,8,9]];
const res4 = arr4.reduce((pre,cur)=>{
return pre.concat(cur)
},[])
console.log('扁平一个二维数组',res4);
3、对象数组去重
const hash = {};
chatLists = chatLists.reduce((obj,next)=>{
const hashId = `${next.topic}_${next.stream_id}`;
if(!hash[hashId]){
hash[`${next.topic}_${next.stream_id}`]=true;
obj.push(next)
}
return obj;
},[])
4、compose函数
redux compose 源码实现
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)))
}