Array.prototype.reduce()

97 阅读1分钟

函数特点:

  • reduce()对于空数组是不会执行回调函数的
  • 如果没有初始值,循环次数会比有初始值的多走一遍

函数用法:

Array.prototype.reduce((previousValue, currentValue, currntIndex, array) => {}, initialValue);
// 参数详情:
// previousValue - 最终返回的值,若有初始值initialValue则使用初始值,否则使用数组的第一个值
// currentValue - 当前值
// currntIndex - 当前索引
// array - 当前数组本身

使用场景

  • 求和运算【求积同理】
// 数组成员都是number
[1, 2, 3, 4, 5].reduce((sum, cur) => {
    return sum += cur;
}, 0); // 15

// 数组成员都是对象
[{num: 1}, {num: 2}, {num: 3}, {num: 4}, {num: 5}].reduce((sum, cur) => {
    return sum += cur.num;
}, 0); // 15
  • 数组去重
const ary = [1,2,3,4,5,2,6,6,2,1,3];
const obj = {};
ary.reduce((result, cur) => {
    if (obj[cur]) {
        return result;
    } else {
        obj[cur] = true;
        result.push(cur);
        return result;
    }
}, []); // [1, 2, 3, 4, 5, 6]
  • 将二维数组转为一维数组
const ary = [[1,2,3], 1, 2, 4, [5]];
ary.reduce((result, cur) => {
    return result.concat(cur);
}, []); // [1, 2, 3, 1, 2, 4, 5]
  • 将多维数组转为一维数组
const ary = [[0, 1], [2, 3], [4,[5,6,7]], 8];
const newAry = (ary) => {
    return ary.reduce((res, cur) => {
         return res.concat(Array.isArray(cur) ? newAry(cur) : cur); // 多了一层递归判断
    }, []);
};
console.log(newAry(ary)); // [0,1,2,3,4,5,6,7,8]
  • 计算数组每个元素出现的次数
const ary = ['a', 'b', 'c', 'd', 'a', 'b'];
ary.reduce((result, cur) => {
    if (cur in result) {
        result[cur] += 1;
    } else {
        result[cur] = 1;
    }
    return result;
}, {}); // {a: 2, b: 2, c: 1, d: 1}
  • 取最大值【最小值同理】
[1,2,3,4,5].reduce((res, cur) => {
    return res = res > cur ? res : cur
}); // 5

手写实现

Array.prototype.myReduce = function(fn, initialValue) {
    let ary = Array.prototype.slice.call(this);
    if (ary.length === 0) throw new TypeError('Reduce of empty array with no initial value');
    let result = initialValue;
    for (let i = 0; i < ary.length; i++) {
        if (result === undefined && i === 0) {
            result = ary[0];
            continue;
        }
        result = fn.call(null, result, ary[i], i, this);
    }
    return result;
}