数组循环过程中元素删除的坑(splice方法使用的注意事项)

611 阅读2分钟

前言

日常在做数组的数据处理过程中,个人使用map方法会比较多,然后在一个明媚的下午,就出现问题了,当我使用map方法遍历一段数组,并在遍历中加入判断,如下:

    const arr = [1, 2, 3, 4]
    arr?.map((item, index) => {
        if (item > 0) {
            arr.splice(index, 1)
        }
    })
    console.log(arr);   [2,4]

很明显我想要的是一个空数组,但是实际上获取到的却是 [2,4] ,这让我有点纳闷,不过既然此路不通,那我就换一种写法,使用 delete方法(一般对象的元素删除可使用delete,但数组不建议用,我是学艺不精,惭愧),如下:

    const arr = [1, 2, 3, 4]
    arr?.map((item, index) => {
        if (item > 0) {
            delete arr[index]
        }
    })
    console.log(arr);    [empty*4]

delete.png

emmm...好像也有点不对劲,数组的length还是4,如果我要判空的话,就没法用length===0来判断了,意识到问题开始不对劲,于是技术贫瘠的我开始使用百度大法。

首先是 splice() 为什么没有成功删除所有元素 ?

当我们使用splice方法时,该方法实现的是将这个元素删除后,后面的元素会前移到当前下标,在例子当中,当第一轮遍历的时候,删除了下标为0的arr[0]=1之后,下标为0的值就会变成arr[0]=2,下标为1的值即arr[1]=3,依次类推,那么在第二轮遍历的时候,arr[1]=3就会被删除,此时arr[1]=4。最终呈现的效果就是想要删除所有元素,变成了删除一半的元素,哭唧唧。

splice()解决方法

解决方法很多,我采用的是更换遍历方法为for循环,通过每一次删除元素后,下标也同时减 1,如下:

    const arr = [1, 2, 3, 4]
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] > 0) {
            arr.splice(i, 1)
            i--
        }
    }
    console.log(arr);    // []

就很棒!!!

第二个就是如何处理delete删除后的数组为空呢 ?

最直接的建议就是不用 delete 删除数组的元素,当然也有处理方法,这里我们可以选用将数组转换成字符串,如下:

    const arr = [1, 2, 3, 4]
    arr?.map((item, index) => {
        if (item > 0) {
            delete arr[index]
        }
    })
    let str = arr.toString()
    console.log('str1', str);   // ,,,
    str = str.replace(/,/g, "")  // 去除逗号
    console.log('str2', str);    // 
    const arr1 = str.split('')
    console.log('arr1', arr1);  // []

delete2.png 以上方法如果有不足之处或者有更好的方法,可以在评论区留言,谢谢。