在循环中删除数组元素

109 阅读2分钟

在代码的编写当中,有时候我们会经常遇到这样的一种情况,尤其是在删除或者是批量删除的时候,我们会再循环当中删除数组,而这样删除有时候很容易就会出错。

让我们来看一段代码

var data = [1,2,3,4,5]

data.forEach((i,index)=>{
    // if(i == 1) 这个条件可以切换成为你所需要的
    if(i == 1){
        data.splice(index,1)
    }
})
console.log(data)
// [2,3,4,5]

这是最简单的在循环中删除数据,是没有问题的,但是当我们删除更多数据的时候,有时候就会出现问题

var data = [1,2,3,4,5]
var arr = [1,2]
data.forEach((i,index)=>{
    console.log(i,arr,arr.includes(i))
    if(arr.includes(i)){
        data.splice(index,1)
    }})
console.log(data)

// 1 (2) [1, 2] true
// 3 (2) [1, 2] false
// 4 (2) [1, 2] false
// 5 (2) [1, 2] false
// (4) [2, 3, 4, 5]

可以看到,最终的data数组只删除了1,但是把2给漏掉了,原因是因为splice()方法是根据index来删除的,由此导致1删除之后,重新循环时,2的下标由原来的1变成了0,而循环是从0开始的,等到循环2的时候,已经是下标1的循环了,所以2自动跳出了循环,这是循环中写删除可能会遇到的问题。

后来发现可以这么写

var data = [1,2,3,4,5]
var arr = [1,2]
arr.forEach((i)=>{
    data.forEach((value,index)=>{
        if(value == i){
            data.splice(index,1)
        }
    })
})
console.log(data)

这样循环的主体由data变成arrdata的下标改变就没有关系了

当然,这种写法只是简单的删除数据的方法,偶尔,还会有在数组中删除对象的需求,这个时候,一般会这么去写

var data = [{id:1},{id:2},{id:3},{id:4}]
var arr= [{id:1},{id:2}]

const arr1 = data.filter(i=>arr.every(j=>j.id != i.id))
console.log(arr1)
// (2) [{id:3}, {id:4}]

这种一般适用于有id这种特殊标识的