遍历数组并删除项目,而不会中断循环

本文翻译自:Looping through array and removing items, without breaking for loop

I have the following for loop, and when I use splice() to remove an item, I then get that 'seconds' is undefined. 我有以下for循环,当我使用splice()删除项目时,然后得到“ seconds”是不确定的。 I could check if it's undefined, but I feel there's probably a more elegant way to do this. 我可以检查它是否未定义,但我觉得可能有一种更优雅的方法。 The desire is to simply delete an item and keep on going. 我们的愿望是简单地删除项目并继续进行。

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);
    }           
}

#1楼

参考:https://stackoom.com/question/fSpg/遍历数组并删除项目-而不会中断循环


#2楼

Although your question is about deleting elements from the array being iterated upon and not about removing elements (in addition to some other processing) efficiently, I think one should reconsider it if in similar situation. 尽管您的问题是关于从要迭代的数组中删除元素而不是有效地删除元素(除了某些其他处理),但我认为如果处于类似情况,则应该重新考虑它。

The algorithmic complexity of this approach is O(n^2) as splice function and the for loop both iterate over the array (splice function shifts all elements of array in the worst case). 这种方法的算法复杂度是O(n^2)因为剪接函数和for循环都在数组上迭代(在最坏的情况下,剪接函数会移动数组的所有元素)。 Instead you can just push the required elements to the new array and then just assign that array to the desired variable (which was just iterated upon). 相反,您可以将所需的元素推到新数组中,然后将该数组分配给所需的变量(刚刚对其进行迭代)。

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;

Since ES2015 we can use Array.prototype.filter to fit it all in one line: 从ES2015开始,我们可以使用Array.prototype.filter使其全部适合一行:

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

#3楼

Auction.auctions = Auction.auctions.filter(function(el) {
  return --el["seconds"] > 0;
});

#4楼

This is a pretty common issue. 这是一个很常见的问题。 The solution is to loop backwards: 解决方案是向后循环:

for (var i = Auction.auctions.length - 1; i >= 0; i--) {
    Auction.auctions[i].seconds--;
    if (Auction.auctions[i].seconds < 0) { 
        Auction.auctions.splice(i, 1);
    }
}

It doesn't matter if you're popping them off of the end because the indices will be preserved as you go backwards. 是否从头开始弹出都没关系,因为索引将在您向后移动时保留。


#5楼

Try to relay an array into newArray when looping: 循环时尝试将数组中继到newArray中:

var auctions = Auction.auctions;
var auctionIndex;
var auction;
var newAuctions = [];

for (
  auctionIndex = 0; 
  auctionIndex < Auction.auctions.length;
  auctionIndex++) {

  auction = auctions[auctionIndex];

  if (auction.seconds >= 0) { 
    newAuctions.push(
      auction);
  }    
}

Auction.auctions = newAuctions;

#6楼

Here is another example for the proper use of splice. 这是正确使用接头的另一个示例。 This example is about to remove 'attribute' from 'array'. 本示例将要删除“数组”中的“属性”。

for (var i = array.length; i--;) {
    if (array[i] === 'attribute') {
        array.splice(i, 1);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值