从Javascript数组中删除多个对象突破了一半

Removing Multiple Objects from Javascript Array Breaks Half Way Through

本文关键字:对象 突破 一半 Javascript 数组 删除      更新时间:2023-09-26

我有一个由几百个JSON对象组成的数组。。。

var self.collection = [Object, Object, Object, Object, Object, Object…]

每一个看起来都是这样的。。。

0: Object
   id: "25093712"
   name: "John Haberstich"

我在数组中反复搜索每个Array.id,看看它是否与第二个数组中的任何id匹配。。。

   var fbContactIDs = ["1072980313", "2502342", "2509374", "2524864", "2531941"] 
   $.each(self.collection, function(index, k) {
        if (fbContactIDs.indexOf(k.id) > -1) {
            self.collection.splice(index, 1);
        };
    });

然而,这段代码只能拼接self-collection数组中的三个对象,然后它会中断并给出以下错误:

Uncaught TypeError: Cannot read property 'id' of undefined 

导致错误的行是这一行。。。

if (fbContactIDs.indexOf(k.id) > -1) {

有人能告诉我我在这里做错了什么吗?

因为收集的长度会改变,所以技巧是从的后面循环到前面

for (var index = self.collection.length - 1; index >= 0; index--) {
    k = self.collection[index];
    if (fbContactIDs.indexOf(k.id) > -1) {
        self.collection.splice(index, 1);
    };
}

在迭代数组时不应更改数组的长度。

您要做的是过滤,并且有一个特定的功能。例如:

[1,2,3,4,5,6,7,8,9,10].filter(function(x){ return (x&1) == 0; })

将只返回偶数。

在您的情况下,解决方案可能只是:

self.collection = self.collection.filter(function(k){
    return fbContactIDs.indexOf(k.id) > -1;
});

或者,如果其他人保留了对self.collection的引用,而你需要在原地对其进行突变:

self.collection.splice(0, self.collection.length,
                       self.collection.filter(function(k){
    return fbContactIDs.indexOf(k.id) > -1;
}));

如果出于某种原因,您喜欢一次处理一个元素,而不是使用filter,并且需要就地处理,那么一种简单的方法是读写方法:

var wp = 0; // Write ptr
for (var rp=0; rp<L.length; rp++) {
    if (... i want to keep L[x] ...) {
        L[wp++] = L[rp];
    }
}
L.splice(wp);

从数组中一次移除一个元素是O(n**2)操作(因为对于移除的每个元素,以下所有元素都必须向下滑动一个位置),所以读写方法是O(n)