遍歷數組並刪除項目,而不會中斷循環

本文翻譯自: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);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章