我有以下for循环,当我使用splice()删除一个项目时,我得到'seconds'是未定义的。我可以检查它是否未定义,但我觉得可能有一种更优雅的方式来做到这一点。他们的愿望是简单地删除一个项目,然后继续前进。

for (i = 0, len = Auction.auctions.length; i < len; i++) {
    auction = Auction.auctions[i];
    Auction.auctions[i]['seconds'] --;
    if (auction.seconds < 0) { 
        Auction.auctions.splice(i, 1);
    }           
}

当前回答

为什么在.splice上浪费CPU周期?该操作必须一次又一次地执行整个循环以删除数组中的一个元素。

为什么不只是在一个循环中使用传统的2个旗帜?

Const元素= [1,5,5,3,5,2,4]; Const remove = 5 I = 0 For(令j = 0;J < elements.length;j + +) { If(元素[j] !==删除){ 元素[i] =元素[j] 我+ + } } 元素。长度= I

其他回答

删除参数

        oldJson=[{firstName:'s1',lastName:'v1'},
                 {firstName:'s2',lastName:'v2'},
                 {firstName:'s3',lastName:'v3'}]
        
        newJson = oldJson.map(({...ele}) => {
          delete ele.firstName;
          return ele;
          })

它删除和创建新的数组,因为我们在每个对象上使用展开运算符,所以原始数组对象也不会受到损害

举两个例子:

一个例子

// Remove from Listing the Items Checked in Checkbox for Delete
let temp_products_images = store.state.c_products.products_images
if (temp_products_images != null) {
    for (var l = temp_products_images.length; l--;) {
        // 'mark' is the checkbox field
        if (temp_products_images[l].mark == true) {
            store.state.c_products.products_images.splice(l,1);         // THIS WORKS
            // this.$delete(store.state.c_products.products_images,l);  // THIS ALSO WORKS
        }
    }
}

两个例子

// Remove from Listing the Items Checked in Checkbox for Delete
let temp_products_images = store.state.c_products.products_images
if (temp_products_images != null) {
    let l = temp_products_images.length
    while (l--)
    {
        // 'mark' is the checkbox field
        if (temp_products_images[l].mark == true) {
            store.state.c_products.products_images.splice(l,1);         // THIS WORKS
            // this.$delete(store.state.c_products.products_images,l);  // THIS ALSO WORKS
        }
    }
}
Auction.auctions = Auction.auctions.filter(function(el) {
  return --el["seconds"] > 0;
});

虽然你的问题是关于从被迭代的数组中删除元素,而不是关于有效地删除元素(除了一些其他处理),但我认为如果遇到类似情况,应该重新考虑它。

这种方法的算法复杂度是O(n^2)作为拼接函数和for循环都遍历数组(在最坏的情况下,拼接函数移位数组的所有元素)。相反,您可以将所需的元素推入到新数组中,然后将该数组赋值给所需的变量(该变量刚刚被迭代)。

var newArray = [];
for (var i = 0, len = Auction.auctions.length; i < len; i++) {
    auction = Auction.auctions[i];
    auction.seconds--;
    if (!auction.seconds < 0) { 
        newArray.push(auction);
    }
}
Auction.auctions = newArray;

自ES2015以来,我们可以使用Array.prototype.filter将所有内容都放在一行中:

Auction.auctions = Auction.auctions.filter(auction => --auction.seconds >= 0);

当您执行.splice()时,数组正在重新索引,这意味着当一个索引被删除时,您将跳过一个索引,并且缓存的.length已过时。

要修复它,你要么需要在.splice()后面递减i,要么简单地反向迭代…

var i = Auction.auctions.length
while (i--) {
    ...
    if (...) { 
        Auction.auctions.splice(i, 1);
    } 
}

这样,重新索引就不会影响迭代中的下一项,因为索引只影响从当前点到数组末尾的项,并且迭代中的下一项低于当前点。