每日前端手写题--day6

如果你最近想要换工作或者巩固一下自己的前端知识基础,不妨和我一起参与到每日刷题的过程中来,如何?

第六天要刷的手写题如下:

  1. 实现Array.prototype.map

  2. 实现Array.prototype.reduce

  3. 实现Array.prototype.reduceRight

  4. 实现Array.prototype.filter

下面是我自己写的答案:

首先必须要明白map函数的执行原理:

  • 遍历原始数组:对于调用 map() 方法的数组,会遍历每个元素。

  • 对每个元素应用回调函数:对于每个元素,都会调用传递给 map() 方法的回调函数,并传入三个参数:当前元素的值、当前元素的索引和原始数组本身。回调函数用来对每个元素进行处理。

  • 构建新数组:将回调函数返回的结果存储在新的数组中。这些结果按照原始数组的顺序排列,构成了新数组。

  • 返回新数组:当遍历完所有元素并处理完成后,map() 方法返回包含处理结果的新数组。

function myMap (cb) {
    if(!Array.isArray(this)) throw new Error('must be called by array');
    const _stack = [...this];
    const _result = [];
    while (_stack.length) {
        const _v = _stack.pop();
        const _tmp = cb(_v, _stack.length-1, _stack);
        
        _result.push(_tmp);
    }
    return _result;
}

2. 实现Array.prototype.reduce

首先必须要明白reduce函数的执行原理:

  • 初始化累加器:首先,将累加器(accumulator)的初始值设置为指定的初始值(或者默认为数组的第一个元素,如果没有提供初始值)。

  • 遍历数组元素:从数组的第一个元素开始,逐个遍历每个元素。

  • 应用回调函数:对于每个元素,都会调用传递给 reduce() 方法的回调函数,并传入四个参数:累加器、当前元素的值、当前元素的索引和原始数组本身。回调函数用来根据当前元素的值和累加器的值进行计算,并返回新的累加器值。

  • 更新累加器:将回调函数返回的新累加器值,作为下一次迭代的累加器值。

  • 返回最终结果:当遍历完所有元素后,reduce() 方法返回最终的累加器值作为计算结果。

function myReduce (cb, initialValue) {
    if(!Array.isArray(this)) throw new Error('must be called by array');
    let _acc = initialValue ?? this[0];
    const startIndex = Number(initialValue === undefined);
    for (let i = startIndex; i < this.length; i++) {
        _acc = cb(_acc, this[i], i , this);
    }
    return _acc;
}

  • !!需要注意的是cb需要四个形参,这四个参数分别表示的含义为:归并值、当前值、当前序列号、数组本组。

  • !!需要注意的是起始位置startIndex会随着initialValue的存在而改变,如果存在则从0开始,否则将第一个元素作为initialValue并且从序列号为1开始。

3. 实现Array.prototype.reduceRight

首先必须要明白reduceRight函数的执行原理:

  • 初始化累加器:首先,将累加器(accumulator)的初始值设置为指定的初始值(或者默认为数组的最后一个元素,如果没有提供初始值)。

  • 逆向遍历数组元素:从数组的最后一个元素开始,逐个逆向遍历每个元素。

  • 应用回调函数:对于每个元素,都会调用传递给 reduceRight() 方法的回调函数,并传入四个参数:累加器、当前元素的值、当前元素的索引和原始数组本身。回调函数用来根据当前元素的值和累加器的值进行计算,并返回新的累加器值。

  • 更新累加器:将回调函数返回的新累加器值,作为下一次迭代的累加器值。

  • 返回最终结果:当逆向遍历完所有元素后,reduceRight() 方法返回最终的累加器值作为计算结果。

function myReduce (cb, initialValue) {
    if(!Array.isArray(this)) throw new Error('must be called by array');
    let _acc = initialValue ?? this.at(-1);
    const startIndex = initialValue ? this.length -1 : this.length -2;
    for (let i = startIndex; i > 0; i--) {
        _acc = cb(_acc, this[i], i , this);
    }
    return _acc;
}

!!reduceRight和reduce的区别在于:遍历数组的方向不同,啊这样的话为什么不先把数组翻转过来呢?

4. 实现Array.prototype.filter

首先必须要明白filter函数的执行原理:

  • 创建一个空数组(称为结果数组)来存储满足条件的元素。

  • 遍历原始数组中的每个元素。

  • 对于每个元素,调用传递给 filter() 方法的回调函数,并将当前元素作为参数传递给回调函数。

  • 回调函数根据设定的条件对当前元素进行评估。如果回调函数返回 true,则表示当前元素满足条件,将其添加到结果数组中。

  • 继续遍历原始数组中的下一个元素,并重复步骤 3 和 4,直到遍历完所有元素。

  • 返回结果数组,其中包含满足条件的元素。

function myFilter (cb) {
    if(!Array.isArray(this)) throw new Error('must be called by array');
    const _stack = [...this];
    const _result = [];
    while (_stack.length) {
        const _v = _stack.pop();
        if (cb(_v, _stack.length-1, _stack) === true) {
            _result.push(_v);
        }
    }

    return _result;
}

!!注意: 需要写成:if (cb(_v, _stack.length-1, _stack) === true) 而不是if (cb(_v, _stack.length-1, _stack))

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Web面试那些事儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值