Ich habe die folgende for-Schleife, und wenn ich splice()
ein Element entferne, erhalte ich, dass 'Sekunden' undefiniert sind. Ich könnte überprüfen, ob es undefiniert ist, aber ich denke, es gibt wahrscheinlich einen eleganteren Weg, dies zu tun. Der Wunsch ist, einfach einen Artikel 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);
}
}
javascript
loops
dzm
quelle
quelle
Auction.auctions[i]['seconds']--
stattauction.seconds--
?Antworten:
Das Array wird neu indiziert, wenn Sie a
.splice()
ausführen. Dies bedeutet, dass Sie einen Index überspringen, wenn einer entfernt wird, und Ihr zwischengespeicherter Index.length
veraltet ist.Um es zu beheben, würden Sie müssen entweder zu verringern ,
i
nachdem ein.splice()
oder einfach Iterierte in umgekehrter ...Auf diese Weise wirkt sich die Neuindizierung nicht auf das nächste Element in der Iteration aus, da die Indizierung nur die Elemente vom aktuellen Punkt bis zum Ende des Arrays betrifft und das nächste Element in der Iteration niedriger als der aktuelle Punkt ist.
quelle
Dies ist ein ziemlich häufiges Problem. Die Lösung besteht darin, rückwärts zu schleifen:
Es spielt keine Rolle, ob Sie sie am Ende entfernen, da die Indizes erhalten bleiben, wenn Sie rückwärts gehen.
quelle
Berechnen Sie die Länge jedes Mal durch die Schleife neu, anstatt nur zu Beginn, z.
Auf diese Weise werden Sie die Grenzen nicht überschreiten.
BEARBEITEN: In der if-Anweisung wurde ein Dekrement hinzugefügt.
quelle
Obwohl es bei Ihrer Frage darum geht, Elemente aus dem Array zu löschen, auf dem iteriert wird, und nicht darum, Elemente (zusätzlich zu einer anderen Verarbeitung) effizient zu entfernen, sollte man sie in einer ähnlichen Situation überdenken.
Die algorithmische Komplexität dieses Ansatzes besteht darin, dass
O(n^2)
die Spleißfunktion und die for-Schleife beide über das Array iterieren (die Spleißfunktion verschiebt im schlimmsten Fall alle Elemente des Arrays). Stattdessen können Sie einfach die erforderlichen Elemente in das neue Array verschieben und dieses Array dann der gewünschten Variablen zuweisen (die gerade wiederholt wurde).Seit ES2015 können wir
Array.prototype.filter
alles in einer Zeile zusammenfassen:quelle
quelle
Wenn Sie ES6 + verwenden, warum nicht einfach die Array.filter-Methode verwenden?
Beachten Sie, dass das Ändern des Array-Elements während der Filteriteration nur für Objekte und nicht für Arrays primitiver Werte funktioniert.
quelle
Eine weitere einfache Lösung, um Array-Elemente einmal zu verarbeiten:
quelle
Hier ist ein weiteres Beispiel für die ordnungsgemäße Verwendung von Spleiß. In diesem Beispiel wird 'Attribut' aus 'Array' entfernt.
quelle
An jede Person, die diese sehr grundlegende Frage mit Code mit splice () in einer Schleife beantwortet hat, die Laufzeit O (n 2 ) hat, oder die eine solche Antwort in den sieben Jahren seit dem Posten dieser Frage positiv bewertet hat: Sie sollten schäme dich .
Hier ist eine einfache lineare Zeitlösung 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 ungefähr das Millionenfache dauern.
Beachten Sie, dass dadurch das ursprüngliche Array geändert wird, anstatt ein neues Array zu erstellen. Dies an Ort und Stelle zu tun, kann vorteilhaft sein, z. B. in dem Fall, dass das Array der einzige Speicherengpass des Programms ist. In diesem Fall möchten Sie auch vorübergehend kein weiteres Array mit derselben Größe erstellen.
quelle
Array.splice(i,1)
dass jedes Mal eine neue Array-Instanz erstellt werden würde. Ich bin sehr beschämt.Es gibt bereits viele wundervolle Antworten auf diesen Thread. Ich wollte jedoch meine Erfahrungen teilen, als ich versuchte, "n-tes Element aus Array entfernen" im ES5-Kontext zu lösen.
JavaScript-Arrays verfügen über verschiedene Methoden zum Hinzufügen / Entfernen von Elementen vom Anfang oder Ende. Diese sind:
Im Wesentlichen kann keine der oben genannten Methoden direkt verwendet werden, um das n-te Element aus dem Array zu entfernen.
Dies lässt uns im Grunde nur eine Array-Methode
Array.splice
zum Entfernen des n-ten Elements übrig (es gibt andere Dinge, die Sie auch mit diesen Methoden tun könnten, aber im Zusammenhang mit dieser Frage konzentriere ich mich auf das Entfernen von Elementen):Hier ist der Code, der von der ursprünglichen Antwort (mit Kommentaren) kopiert wurde:
Eine andere bemerkenswerte Methode ist
Array.slice
. Der Rückgabetyp dieser Methode sind jedoch die entfernten Elemente. Auch dies ändert das ursprüngliche Array nicht. Geändertes Code-Snippet wie folgt:Trotzdem können wir das
Array.slice
n-te Element wie unten gezeigt entfernen. Es ist jedoch viel mehr Code (daher ineffizient)quelle
Versuchen Sie, ein Array in einer Schleife an newArray weiterzuleiten:
quelle
Zwei Beispiele, die funktionieren:
quelle
Probieren Sie es aus
quelle
quelle
Sie können einfach durchsehen und verwenden
shift()
quelle