我有以下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);
    }           
}

当前回答

这是一个很常见的问题。解决方案是反向循环:

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

如果你把它们从末端取出来也没关系因为下标会在逆向过程中保留下来。

其他回答

这是这个简单线性时间问题的一个简单线性时间解。

当我运行这个代码片段时,n = 100万,每次调用filterInPlace()需要0.013到0.016秒。一个二次解(例如,公认的答案)将需要它的一百万倍左右。

// Remove from array every item such that !condition(item). function filterInPlace(array, condition) { var iOut = 0; for (var i = 0; i < array.length; i++) if (condition(array[i])) array[iOut++] = array[i]; array.length = iOut; } // Try it out. A quadratic solution would take a very long time. var n = 1*1000*1000; console.log("constructing array..."); var Auction = {auctions: []}; for (var i = 0; i < n; ++i) { Auction.auctions.push({seconds:1}); Auction.auctions.push({seconds:2}); Auction.auctions.push({seconds:0}); } console.log("array length should be "+(3*n)+": ", Auction.auctions.length) filterInPlace(Auction.auctions, function(auction) {return --auction.seconds >= 0; }) console.log("array length should be "+(2*n)+": ", Auction.auctions.length) filterInPlace(Auction.auctions, function(auction) {return --auction.seconds >= 0; }) console.log("array length should be "+n+": ", Auction.auctions.length) filterInPlace(Auction.auctions, function(auction) {return --auction.seconds >= 0; }) console.log("array length should be 0: ", Auction.auctions.length)

注意,这只是修改原始数组,而不是创建一个新数组;这样做是有好处的,例如,在数组是程序的单一内存瓶颈的情况下;在这种情况下,您不希望创建另一个相同大小的数组,即使是临时的。

普通的for循环对我来说更熟悉,我只需要在每次从数组中删除一个项时递减索引

//5个正确,5个错误 Var arr1 =[假,假,真,真,假,真,假,真,真,假]; //从数组中删除false For (var I = 0;I < arr1.length;我+ +){ If (arr1[i] === false){ arr1。拼接(我,1); I——;//如果item被移除,则递减索引 } } Console.log (arr1);//应该是5个true

另一个简单的方法是一次消化数组元素:

while(Auction.auctions.length){
    // From first to last...
    var auction = Auction.auctions.shift();
    // From last to first...
    var auction = Auction.auctions.pop();

    // Do stuff with auction
}

下面是另一个正确使用拼接的例子。本例将从'array'中删除'attribute'。

for (var i = array.length; i--;) {
    if (array[i] === 'attribute') {
        array.splice(i, 1);
    }
}

尝试在循环时将数组中继到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;