656 Stimmen

Schleife durch Array und Entfernen von Elementen, ohne die for-Schleife zu unterbrechen

Ich habe die folgende for-Schleife, und wenn ich verwenden splice() um ein Element zu entfernen, erhalte ich die Meldung, dass "Sekunden" nicht definiert ist. Ich könnte überprüfen, ob es undefiniert ist, aber ich denke, es gibt wahrscheinlich einen eleganteren Weg, dies zu tun. Der Wunsch ist es, einfach ein Element zu löschen und weiterzumachen.

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

24voto

Rubinsh Punkte 4615

Wenn Sie ES6+ verwenden - warum nicht einfach die Array.filter Methode?

Auction.auctions = Auction.auctions.filter((auction) => {
  auction['seconds'] --;
  return (auction.seconds > 0)
})  

Beachten Sie, dass das Ändern des Array-Elements während der Filteriteration nur für Objekte funktioniert und nicht für Arrays mit primitiven Werten.

18voto

Don Hatch Punkte 4507

Hier ist eine einfache Lösung in linearer Zeit für dieses einfache lineare Zeitproblem.

Wenn ich dieses Snippet mit n = 1 Million ausführe, dauert jeder Aufruf von filterInPlace() 0,013 bis 0,016 Sekunden. Eine quadratische Lösung (z. B. die akzeptierte Antwort) würde etwa eine Million Mal so lange dauern.

// 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)

Beachten Sie, dass dies das ursprüngliche Array an Ort und Stelle modifiziert, anstatt ein neues Array zu erstellen; dies kann vorteilhaft sein, z.B. wenn das Array der einzige Speicherengpass des Programms ist; in diesem Fall möchten Sie kein weiteres Array der gleichen Größe erstellen, auch nicht vorübergehend.

15voto

Accountant م Punkte 5859

Die normale for-Schleife ist mir vertrauter, ich muss nur den Index jedes Mal dekrementieren, wenn ich ein Element aus dem Array entferne

//5 trues , 5 falses
var arr1 = [false, false, true, true, false, true, false, true, true, false];

//remove falses from array
for (var i = 0; i < arr1.length; i++){
    if (arr1[i] === false){
        arr1.splice(i, 1);
        i--;// decrement index if item is removed
    }
}
console.log(arr1);// should be 5 trues

14voto

Pablo Punkte 5555

Eine weitere einfache Lösung, um ein Array-Element einmal zu verdauen:

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
}

11voto

daniel.szaniszlo Punkte 373

Hier ist ein weiteres Beispiel für die richtige Verwendung von Spleiß. In diesem Beispiel geht es darum, 'attribute' aus 'array' zu entfernen.

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X