手写数组方法(二十):reduce

163 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第28天,点击查看活动详情

个人认为reduce是所有数组方法中最晦涩难懂的,也是最具魔法的一个方法。对其既爱又恨。reduce在很多情况下能达到意想不到的处理结果,前提是你把该方法吃透了。今天就带大家来啃下这块硬骨头!

语法

reduce(callbackFn[, initialValue])

参数

  • callbackFn:一个 “reducer” 函数,包含四个参数:
    • previousValue:上一次调用 callbackFn 时的返回值。在第一次调用时,若指定了初始值 initialValue,其值则为 initialValue,否则为数组索引为 0 的元素 array[0]
    • currentValue:数组中正在处理的元素。在第一次调用时,若指定了初始值 initialValue,其值则为数组索引为 0 的元素 array[0],否则为 array[1]
    • currentIndex:数组中正在处理的元素的索引。若指定了初始值 initialValue,则起始索引号为 0,否则从索引 1 起始。
    • array:用于遍历的数组。
  • initialValue:初始值, 可选。作为第一次调用 callback 函数时参数 previousValue 的值。若指定了初始值 initialValue,则 currentValue 则将使用数组第一个元素;否则 previousValue 将使用数组第一个元素,而 currentValue 将使用数组第二个元素。

返回值

使用 “reducer” 回调函数遍历整个数组后的结果。

说了这么多,还是直接上例子来的直观些:

例子

求数组元素的和

image.png

等价于:

image.png

我们给了个初始值0,第一种情况不给初始值:1+2+3。第二种情况则是0+1+2+3。结果一样的。举一反三。求数组的积:

求数组的积

image.png

啊咧?结果不一样耶!当然不一样,你初始值传的可是0啊,0乘以任何数都是0呢,这边初始值应该是1!

image.png

找出数组中的最值

image.png

image.png

数组去重

image.png

我们给个初始值[]。如果数组里没有当前的元素,则添加进来,否则直接返回之前的结果。这样一顿操作后,出现过的元素就会被过滤掉了。

手写

Array.prototype._reduce = function(callback, initialValue) {
    let idx =  initialValue ? 0 : 1;
    let res = initialValue ? initialValue : this[0];
    for(let i = idx; i < this.length; i++) {
        res = callback.call(null, res, this[i], i, this);
    }
    return res;
}

假如传了初始值,我们是从数组的第一位开始遍历。假如没传,初始值为数组第一位,从数组的第二位开始遍历。总体来说,reduce的手写比起它的用法来说相对还是简单的。不知道你有没有学会呢?