前端攻城师必须熟悉掌握的reduce方法

674 阅读3分钟

reduce语法

arr.reduce(callback(pre, cur, index, arr), init)

reduce()接收两个参数,第一个callback函数为必需参数,第二个init作为初始值为可选参数,会作为第一次调用callback函数的第一个参数值,如果没有init,callback则会调用arr数组的第一个参数的值;

使用条件

使用reduce()方法,必须满足(arr.length > 0 || arr.length >=0 && init)这两个条件,否则reduce()会报typeError,如下:


参数说明

callback(pre, cur, index, arr)中的4个参数:

  • pre    :初始值为init或者为arr数组的第一个值,上一次回调的返回累计值;
  • cur    :数组中正在处理的当前值;
  • index :数组中正在处理的当前值的索引(如果提供init,索引index从0开始;没有init,则索引从1开始);
  • arr     :当前调用reduce()的数组;

init:作为第一次调用callback函数时的第一个参数的值;

常用reduce的例子

1,求数组里所有值得和

let arr = [12,23,10,23,10];
let sum = arr.reduce((pre, cur) => {
    return pre + cur;
}, 0);
console.log(sum); // 78

2,累加对象数组里的值

let arr = [{sum: 10}, {sum: 20}, {sum: 30}];
let sumAll = arr.reduce((pre, cur) => {
    return pre + cur.sum
}, 0); // 初始值可给可不给
console.log(sumAll); // 60

3,将二维数组转化为一维数组

let arr = [[1,2],[3,4], [5,6]];
let flattened = arr.reduce((pre, cur) => {
    return pre.concat(cur);
}, []);
console.log(flattened); // [1, 2, 3, 4, 5, 6]

4,将数组中的多维数组都转化为一维数据

let arr = [11,[22,33, [44,55,66, [77]]],[88],99, [100, 101]];
const flattened = (arr) => {
    return arr.reduce((pre, cur) => {
        return Array.isArray(cur) ? pre.concat(flattened(cur)) : pre.concat(cur);
    }, [])
};
console.log(flattened(arr)); // [11, 22, 33, 44, 55, 66, 77, 88, 99, 100, 101]

5,计算数组中每个元素出现的次数

let arr = ['apple', 'orange', 'banana','orange', 'banana', 'orange'];
let countNames = arr.reduce((pre, cur) => {
    if (cur in pre) {
        pre[cur]++;
    } else {
        pre[cur] = 1;
    }
    return pre;
}, {});
console.log(countNames); // {apple: 1, orange: 3, banana: 2}

6,按某一个属性对Object分类

let arr = [
    {name: 'apple', price: 4},
    {name: 'orange', price: 5},
    {name: 'banana', price: 4}
];
// 把相同价格的水果分类
const teamGroup = (arr, property) => {
    return arr.reduce((pre, cur) => {
        let key = cur[property];
         if (!pre[key]) {
            pre[key] = [];
         }
         pre[key].push(cur);
         return pre;
    }, {})
};
console.log(teamGroup(arr, 'price'));
// {4: [{name: 'apple', price: 4},{name: 'banana', price: 4}], 5: [{name: 'orange', price: 5}]}

7,数组去重

let arr = ['a','b','a','b','c','d','e','a','c'];
let order = arr.reduce((pre, cur) => {
  if (pre.indexOf(cur) === -1) {
    pre.push(cur);
  }
  return pre; 
}, []);
console.log(order); // ["a", "b", "c", "d", "e"]

8,使用reduce实现map函数

if(!Array.prototype._myMap){
    Array.prototype._myMap = function(callback, thisArg){
        // this指向._myMap;
        return this.reduce((pre, cur, index, array) => {
            console.log(thisArg);
            pre[index] = callback.call(thisArg, cur, index, array);
            return pre;
        }, [])
    }
};

[20,30,40]._myMap(item => item*2); // [40,60,80]

9,使用reduce实现filter函数

if(!Array.prototype._myFilter){
    Array.prototype._myFilter = function(callback, thisArg){
        return this.reduce((pre, cur, index, array) => {
            pre[index] = callback.call(thisArg, cur, index, array) ? callback.call(thisArg, cur, index, array) : null;
            return pre;
        }, [])
    }
};
[20,30,40,100,90]._myFilter((item)=> item > 30); //[40, 100, 90]

reduceRight()方法

reduceRight()方法与reduce()方法的功能作用一致,不同之处在于reduce是从左-->右的顺序来累加计算,而reduceRight是从右-->左的顺序来执行累加计算的;

这里就不再对reduceRight进行整理;

小结

通过整理本小节内容,让自己对reduce又有了熟悉的认识,就当温故而知新啦;