手写数组方法(九):splice

486 阅读4分钟

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

今天带大家来熟悉下数组方法之splice,并在文末手写之

语法

array.splice(index, howmany, item1, ...., itemX)

参数

  • index: 可选。规定从何处添加/删除元素。该参数是开始插入和(或)删除的数组元素的下标,必须是数字。注意,该参数可不传
  • howmany: 可选。规定应该删除多少元素。必须是数字。 如果未规定此参数,则删除从 index开始到原数组结尾的所有元素。
  • item1, ..., itemX: 可选。要添加到数组的新元素。

返回值

如果从数组对象中删除了元素,则返回的是含有被删除的元素的数组, 否则返回一个空数组。

光说不练假把式,我们接下来看看具体示例,帮助我们更好认识这些参数。

示例

参数index不传

let list = ['a', 'b', 'c'];
let res = list.splice();
console.log(res);

image.png

只传index参数

index为数字时

let list = ['a', 'b', 'c'];
let res = list.splice(0);
console.log(res);

let list = ['a', 'b', 'c'];
let res = list.splice(1);
console.log(res);

let list = ['a', 'b', 'c'];
let res = list.splice(2);
console.log(res);

let list = ['a', 'b', 'c'];
let res = list.splice(3);
console.log(res);

let list = ['a', 'b', 'c'];
let res = list.splice(4);
console.log(res);

let list = ['a', 'b', 'c'];
let res = list.splice(-1);
console.log(res);

let list = ['a', 'b', 'c'];
let res = list.splice(-2);
console.log(res);

let list = ['a', 'b', 'c'];
let res = list.splice(-3);
console.log(res);

let list = ['a', 'b', 'c'];
let res = list.splice(-4);
console.log(res);

image.png

可以看到,只传index,并且index是数字的话,删除的元素是从index到数组长度减一(前闭后闭)。当index >= 数组长度的时候,表示不删除元素。当index为负数的时候,是从数组末尾向前删除,删除的元素个数为index的绝对值,当绝对值超出数组长度时,与等于数组长度时效果一样。

index为其他类型时

image.png

我们发现只有在true以及字符串'1'的时候,效果同数字1,其他情况则全部删除。值得一提的是,false其实和数字0是一样的效果,这边做了数值转换。

第二个参数howmany

当不传第二个参数时,我们默认是删除到数组末尾,即如果index1,则从数组下标1开始删除到数组末尾。index为负数时,其实可以理解为,从后面往前数第几个开始删除,到数组末尾。

不传的情况,上边我们已经验证过了,下边我们验证下传了的情况。

image.png

可以看到,第二个参数定义了要删除的元素的个数,如果howmany大于从index开始到结束的元素个数,则删除到数组末尾,如果howmany为负数,效果同0。另外对于其他数据类型,在经过数值转换后如果不是数字,则效果同0,即不删除元素。

第三个及之后的参数

这些参数定义了添加到数组中的元素,即经过前两个参数操作后,在下标index 位置添加元素。

image.png

这边很容易写错,因为常规思维都是在某个元素后面添加,所以想当然在下标index后添加,实际上是在下标index处添加,一定要注意

比如我们要删除'b',再在原先'b'的位置处添加一个'd':

image.png

手写

理清思路

  • 函数接收任意个参数
  • 第一个参数必须是数字,规定从何处添加/删除元素。不是数字会做数值转换,转换后如果不是数字,效果同数字0
  • 第二个参数必须是数字, 规定应该删除多少元素,不是数字同上。
  • 第三个参数开始是要添加的元素
  • 返回含有被删除元素的数组 根据需求,不难写出以下代码:
Array.prototype._splice = function (...args) {
    let deletes = [];
    let appends = [];
    let heads = [];
    let tails = [];
    let index, howmany;
    if (args.length === 0) return res;
    index = args[0];
    index = Number(index);
    index = index === index ? index : 0;
    if (args.length > 1) {
        howmany = args[1];
        howmany = Number(howmany);
        howmany = howmany === howmany ? howmany : 0;
    }
    if (args.length > 2) {
        appends = args.filter((v, i) => i > 1);
    }
    for (let i = 0; i < this.length; i++) {
        if (i < index) {
            heads.push(this.shift());
        }
        if (i <= index + howmany - 1) {
            deletes.push(this.shift());
        }
        if (index + howmany <= i) {
            tails.push(this.shift());
        }
    }
    this.unshift(...heads);
    this.push(...appends);
    this.push(...tails);
    return deletes;
};

今天关于数组splice的介绍就讲到这里,关注我获取更多有关数组方法的讲解,后续会持续更新。我是末世未然,一个爱折腾的新晋奶爸,祝好