ES中reduce的一些用法记录

以前一直不怎么用reduce,用过之后觉得这个方法非常好,能优雅的解决一些困扰人的结果运算, rxjs中很多地方都有scan(跟reduce类似)身影

MDN文档

js reduce的一些使用

reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终为一个值,是ES5中新增的又一个数组逐项处理方法,那reduce方法跟foreach、map等数组方法又有啥区别呢。

arr.reduce(callback[, initialValue]) — More From MDN
callback(一个在数组中每一项上调用的函数,接受四个函数:)
previousValue(上一次调用回调函数时的返回值,或者初始值)
currentValue(当前正在处理的数组元素)
currentIndex(当前正在处理的数组元素下标)
array(调用reduce()方法的数组)
initialValue(可选的初始值。作为第一次调用回调函数时传给previousValue的值)

另一些高级用法:https://www.jb51.net/article/132324.htm

1、求和
var arr=[1,2,3,4];
var total=arr.reduce((pre,cur)=>{
    return pre+cur;
});
根据定义还可以传初始值
var total=arr.reduce((pre,cur)=>pre+cur,10);

2、计算对象数组的某字段最大值对象
var objArr=[
    {"type":"java","count":10},
    {"type":"c++","count":20},
    {"type":"javascript","count":100},
    {"type":"c#","count":10},
    {"type":"python","count":30}
]

let maxObj=objArr.reduce((pre,cur)=>{
    return pre.count>cur?pre:cur;
});
//返回 {"type":"javascript","count":100}

3、特殊处理
以上面的对象数组为例, 要求返回 var languages='java,c++,javascript,c# 和 python';
var languages=objArr.reduce((pre,cur,index,arr)=>{
    if(index===0){    //第一项
        return pre+cur.type;
    }else if(index=== arr.length-1){  //最后一项
        return pre+' 和 '+cur.type;
    }
    return pre+','+cur.type
},'');  //初始值是空字符串


4、一串字符串中每个字母出现的次数?
var arrString = 'abcdaabddcca';
arrString.split('').reduce(function (prev, curr) {
    prev[curr] ? prev[curr]++ : prev[curr] = 1;
    return prev;
}, []);
// [a: 4, b: 2, c: 3, d: 3]

//某个数在数组中出现的次数
const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0);
countOccurrences([1, 2, 3, 2, 2, 5, 1], 1);

//如果初始值换成对象 
var arrString = 'abcdaabddcca';
arrString.split('').reduce(function (prev, curr) {
    prev[curr] ? prev[curr]++ : prev[curr] = 1;
    return prev;
}, {});
{a: 4, b: 2, c: 3, d: 3}

5、字母游戏
const anagrams = str => {
 if (str.length <= 2) {  //如果字符串的长度小于等于2
   return str.length === 2 ? [str, str[1] + str[0]] : str;
 }
 return str.split("").reduce((acc, letter, i) => {
   return acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val));
 }, []);
}
 
anagrams("abc"); // 结果会是什么呢?

6、计算数组对象重复个数 (如下:如果code相同,则数量+1)
var list = [
    {"date":'2018-08-01',"time":'11:21:20',"code":'11111',"name":'民乐工业园1栋东山口民乐工业',"lng":'112.203909',"lat":'31.021737',"img":'http://192.168.0.12:8080/images/usr/'},
    {"date":'2018-08-02',"time":'11:21:20',"code":'11112',"name":'民乐工业园1栋东山口民乐工业',"lng":'112.202104',"lat":'31.023602',"img":'http://192.168.0.12:8080/images/usr/'},
    {"date":'2018-08-02',"time":'11:21:20',"code":'11112',"name":'民乐工业园1栋东山口民乐工业',"lng":'112.202104',"lat":'31.023602',"img":'http://192.168.0.12:8080/images/usr/'},
    {"date":'2018-08-03',"time":'11:21:20',"code":'11113',"name":'民乐工业园1栋东山口民乐工业',"lng":'112.203909',"lat":'',"img":'http://192.168.0.12:8080/images/usr/'}
];
let obj={};  //通过一个对象来过渡
var filterArr=list.reduce((pre,cur)=>{
    if(obj[cur.code]){
        obj[cur.code]++;  
        pre.find(c=>c.code==cur.code).count++;
    }else{
        obj[cur.code]=1;
        pre.push(Object.assign({},{count:obj[cur.code]},cur));
    }                    
    return pre;
},[]);
console.log(filterArr);

7、分组
const groupBy = (arr, func) =>
arr.map(typeof func === 'function' ? func : val => val[func]).reduce((acc, val, i) => {
 acc[val] = (acc[val] || []).concat(arr[i]);
 return acc;
}, {});
groupBy([6.1, 4.2, 6.3], Math.floor); 
groupBy(['one', 'two', 'three'], 'length');

你可能感兴趣的:(ES中reduce的一些用法记录)