Javascript数组研究03_手写实现_fill_filter_find_findIndex_findLast_findLastIndex

6 Array.fill()

6.1 基本介绍

fill() 方法用一个固定值填充一个数组中从起始索引(默认为 0)到终止索引(默认为 array.length)内的全部元素。它返回修改后的数组。

fill(value)
fill(value, start)
fill(value, start, end)

输入参数

  • value:用来填充数组元素的值。
  • start(可选):开始填充的位置,默认值为 0,索引处理方法和copyWithin一致。
  • end(可选):停止填充的位置(不包含该位置),默认值为 this.length,索引处理方法和copyWithin方法一致。

输出:修改后的原数组。

注意事项

  • 该方法会改变原数组,是修改方法
  • 对于稀疏数组,空槽也会被value填充。
  • 通用的方法
  • 在空数组上不会有任何处理
  • 如果value值为对象的时候,会使填充的所有内容都是执行同一对象
6.2 手写实现
MyArray.prototype.fill = function(value, start = 0, end = this.length) {
    const length = this.length;

    // 转换为整数
    let relativeStart = Number(start);
    let relativeEnd = Number(end);

    // 处理 NaN
    if (isNaN(relativeStart)) relativeStart = 0;
    if (isNaN(relativeEnd)) relativeEnd = length;

    // 转换为整数,向零方向取整
    let to = relativeEnd < 0 ? Math.max(length + relativeEnd, 0) : Math.min(relativeEnd, length);
    let from = relativeStart < 0 ? Math.max(length + relativeStart, 0) : Math.min(relativeStart, length);

    if (from >= length || to <= from) return this;

    for (let i = from; i < to; i++) {
        this[i] = value;
    }

    return this;
};


let arr_1 = new MyArray(1, 2, 3)
console.log(arr_1.fill(4)); // [4, 4, 4]
arr_1 = new MyArray(1, 2, 3)
console.log(arr_1.fill(4, 1)); // [1, 4, 4]
arr_1 = new MyArray(1, 2, 3)
console.log(arr_1.fill(4, 1, 2)); // [1, 4, 3]
arr_1 = new MyArray(1, 2, 3)
console.log(arr_1.fill(4, 1, 1)); // [1, 2, 3]
arr_1 = new MyArray(1, 2, 3)
console.log(arr_1.fill(4, 3, 3)); // [1, 2, 3]
arr_1 = new MyArray(1, 2, 3)
console.log(arr_1.fill(4, -3, -2)); // [4, 2, 3]
arr_1 = new MyArray(1, 2, 3)
console.log(arr_1.fill(4, NaN, NaN)); // [1, 2, 3]
arr_1 = new MyArray(1, 2, 3)
console.log(arr_1.fill(4, 3, 5)); // [1, 2, 3]
arr_1 = new MyArray(1, 2, 3)
console.log(new MyArray(3).fill(4)); // [4, 4, 4]

// 一个简单的对象,被数组的每个空槽所引用
const arr = new MyArray(3).fill({}); // [{}, {}, {}]
arr[0].hi = "hi"; // [{ hi: "hi" }, { hi: "hi" }, { hi: "hi" }]
console.log(arr)

难点总结

  • 处理索引startend 可以使用统一的方法处理索引,然后进行边界判断。
  • 正确判断NaN:当startend为NaN时需要重新处理为默认值

7 Array.filter()

7.1 基本介绍

filter() 方法创建给定数组一部分的浅拷贝,其包含通过所提供函数实现的测试的所有元素。语法如下:

filter(callbackFn)
filter(callbackFn, thisArg)

输入参数

  • callbackFn(element, index, array):用于测试每个元素的函数,返回 true 保留元素,返回 false 不保留。
  • thisArg(可选):执行 callbackFn 时使用的 this 值。

输出:一个新的数组,包含通过测试的元素。

注意事项

  • filter() 不会改变原数组,他是一个复制方法
  • 对于稀疏数组,callbackFn 不会针对空槽调用,空槽也不会出现在新数组中。
  • 如果 callbackFn 改变了数组,则会影响后续的遍历。
7.2 手写实现
MyArray.prototype.filter = function(callFn, thisArg){
    if(typeof callFn !== "function"){
        throw new TypeError(callFn + "is not a callback function")
    }
    let res;
    if(Array.isArray(this)){
        const C = getConstructor(this)
        res = new C()
    }else{
        res = new Array()
    }
    

    for(let i = 0; i < this.length; i ++){
        if(!(i in this)) continue
        if(callFn.call(thisArg, this[i], i, this)){
            res.push(this[i])
        }
    }

    return res
}

function isBigEnough(value) {
    return value >= 10;
}

const arr_2 = new MyArray(12, 5, 8, 130, 44)
const filtered = arr_2.filter(isBigEnough);
console.log(filtered)
// filtered is [12, 130, 44]

console.log(MyArray.prototype.filter.call([1, , undefined], (x) => x === undefined)); // [undefined]

const arrayLike = {
    length: 3,
    0: "a",
    1: "b",
    2: "c",
  };
  console.log(MyArray.prototype.filter.call(arrayLike, (x) => x <= "b"));
  // [ 'a', 'b' ]
  

难点总结

  • 处理空槽:使用 in 操作符检查索引是否存在,跳过空槽。
  • 创建新数组:如何获取正确的对应的构造函数从而返回一致的类型的实例对象是个难点。

8 Array.find()

8.1 基本介绍

find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。语法如下:

find(callbackFn)
find(callbackFn, thisArg)

输入参数

  • callbackFn(element, index, array):用于测试每个元素的函数。
  • thisArg(可选):执行 callbackFn 时使用的 this 值。

输出:满足测试函数的第一个元素的值,或 undefined

注意事项

  • 一旦找到满足条件的元素,方法立即返回,不会继续遍历。
  • 对于稀疏数组,空槽的行为和undefined表现一致
  • 如果在遍历过程中修改了数组,可能会影响结果。
  • find方法是通用的
8.2 手写实现
  MyArray.prototype.find = function(callFn, thisArg){
    if(typeof callFn !== "function"){
        throw new TypeError(callFn + "is not a function")
    }

    for(let i = 0; i < this.length; i++){
        if(callFn.call(thisArg, this[i], i, this)) return this[i]
    }

    return undefined
  }

  const inventory = new MyArray(
    { name: "apples", quantity: 2 },
    { name: "bananas", quantity: 0 },
    { name: "cherries", quantity: 5 },
  )
  const result = inventory.find(({ name }) => name === "cherries");
  console.log(result); // { name: 'cherries', quantity: 5 }

  const arrayLike_2 = {
    length: 3,
    0: 2,
    1: 7.3,
    2: 4,
  };
  console.log(MyArray.prototype.find.call(arrayLike_2, (x) => !Number.isInteger(x)));
  // 7.3

难点总结

  • 提前终止遍历:找到满足条件的元素后立即返回。
  • 处理空槽:和已经学习过的every、filter行为有差异,会对空槽执行回调函数,空槽被视为undefined

9 Array.findIndex()

9.1 基本介绍

findIndex() 方法返回数组中满足提供的测试函数的第一个元素的索引。否则返回 -1。语法如下:

findIndex(callbackFn)
findIndex(callbackFn, thisArg)

输入参数

  • callbackFn(element, index, array):用于测试每个元素的函数。
  • thisArg(可选):执行 callbackFn 时使用的 this 值。

输出:满足测试函数的第一个元素的索引,或 -1

注意事项

  • 一旦找到满足条件的元素,方法立即返回索引,不会继续遍历。
  • 对于稀疏数组,空槽行为和undefined一致
  • 数组在遍历过程中被修改,可能会影响结果。
    -** 通用的**方法
9.2 手写实现
MyArray.prototype.findIndex = function(callbackFn, thisArg) {
    if (typeof callbackFn !== "function") {
        throw new TypeError(callbackFn + ' is not a function');
    }

    for (let i = 0; i < this.length; i++) {
        if (callbackFn.call(thisArg, this[i], i, this)) {
            return i;
        }
    }
    return -1;
};


console.log(MyArray.prototype.findIndex.call([1, , 3],(x) => x === undefined)) // 1
const arrayLike_3 = {
    length: 3,
    0: 2,
    1: 7.3,
    2: 4,
  };
  console.log(
    MyArray.prototype.findIndex.call(arrayLike_3, (x) => !Number.isInteger(x)),
  ); // 1

难点总结

  • 返回索引:与 find() 方法不同,findIndex() 返回索引。
  • 处理空槽:find和findIndex处理空槽行为一致,都会视为undefined进行处理。

10 Array.findLast()

10.1 基本介绍

findLast() 方法从数组末尾开始遍历,返回第一个满足提供的测试函数的元素的值。否则返回 undefined。语法如下:

findLast(callbackFn)
findLast(callbackFn, thisArg)

输入参数

  • callbackFn(element, index, array):用于测试每个元素的函数。
  • thisArg(可选):执行 callbackFn 时使用的 this 值。

输出:满足测试函数的第一个元素的值(从后向前),或 undefined

注意事项

  • 从数组的末尾开始遍历。
  • 对于稀疏数组,空槽行为和undefined一致
  • 如果在遍历过程中修改了数组,可能会影响结果。
10.2 手写实现
MyArray.prototype.findLast = function(callbackFn, thisArg) {
    if (typeof callbackFn !== "function") {
        throw new TypeError(callbackFn + ' is not a function');
    }

    for (let i = this.length - 1; i >= 0; i--) {
        let element = this[i];
        if (callbackFn.call(thisArg, element, i, this)) {
            return element;
        }
    }

    return undefined;
};

难点总结

  • 处理空槽findLastfindIndex以及find处理空槽的行为一致。

11 Array.findLastIndex()

11.1 基本介绍

findLastIndex() 方法从数组末尾开始遍历,返回第一个满足提供的测试函数的元素的索引。否则返回 -1。语法如下:

findLastIndex(callbackFn)
findLastIndex(callbackFn, thisArg)

输入参数

  • callbackFn(element, index, array):用于测试每个元素的函数。
  • thisArg(可选):执行 callbackFn 时使用的 this 值。

输出:满足测试函数的第一个元素的索引(从后向前),或 -1

注意事项

  • 从数组的末尾开始遍历。
  • 对于稀疏数组,空槽行为和undefined一致。。
  • 数组在遍历过程中被修改,可能会影响结果。
  • 该方法是通用方法
11.2 手写实现
MyArray.prototype.findLastIndex = function(callbackFn, thisArg) {
    if (typeof callbackFn !== "function") {
        throw new TypeError(callbackFn + ' is not a function');
    }

    for (let i = this.length - 1; i >= 0; i--) {
        if (callbackFn.call(thisArg, this[i], i, this)) {
            return i;
        }
    }

    return -1;
};

难点总结

  • 处理空槽findfindLastfindIndexfindLastIndex处理行为一致,都是把空槽当作undefined处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

It'sMyGo

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

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

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

打赏作者

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

抵扣说明:

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

余额充值