JavaScript: Wie entfernt man ein bestimmtes Element aus einem Array?
Es gibt zwei Antworten, und welche du willst, hängt an einer Frage, die niemand laut stellt: Willst du ein neues Array, oder willst du dieses hier verändert?
filter oder splice
const a = ["a", "b", "c", "b"];
a.filter(x => x !== "b"); // neues Array
const i = a.indexOf("b");
if (i > -1) a.splice(i, 1); // dieses Array
start : [ 'a', 'b', 'c', 'b' ]
filter !== 'b' : [ 'a', 'c' ] <- removes ALL 'b'
indexOf+splice : [ 'a', 'c', 'b' ] <- removes the FIRST 'b' only
Gleiche Eingabe, verschiedene Ergebnisse, und keines davon ist falsch.
filter
prüft jedes Element, also fliegt jeder Treffer raus.
indexOf
findet eine Position, also fliegt ein Element raus.
Der andere Unterschied:
after filter, original : [ 'a', 'b', 'c', 'b' ]
after splice, original : [ 'a', 'c', 'b' ] <- changed
splice
verändert das Original. Das ist in dem Moment wichtig, in dem noch jemand eine
Referenz auf dasselbe Array hält.
Die Prüfung ist nicht optional
Lässt du das if weg, passiert im Fehlschlag-Fall etwas Bestimmtes und
Schlechtes:
indexOf('zzz') : -1
splice(-1, 1) : [ 'a', 'b', 'c' ] <- removed the LAST item instead of nothing
Ein negativer Index zählt von hinten, -1 heißt also “das letzte”. Die Suche
nach etwas, das gar nicht da ist, löscht ein echtes Element — ohne Fehler, ohne
Warnung, und zwar eines, das du nie genannt hast. Immer auf > -1 prüfen.
delete ist es nicht
delete d[1];
after delete d[1] : [ 'a', <1 empty item>, 'c', 'b' ]
length : 4 <- unchanged
1 in d : false
delete
entfernt den Wert, nicht den Platz. Übrig bleiben ein Loch, eine unveränderte
length und ein Array, das sich in allem, was darüber iteriert, seltsam
verhält.
splice sagt dir, was es genommen hat
splice(1, 2) returned: [ 'b', 'c' ] leaving [ 'a', 'b' ]
Das zweite Argument ist eine Anzahl, kein End-Index, und der Rückgabewert sind die entfernten Elemente — praktisch, wenn du etwas verschieben statt wegwerfen willst.
Nach Index, ohne zu verändern
t.toSpliced(1, 1) : [ 'a', 'c', 'b' ] original still [ 'a', 'b', 'c', 'b' ]
typeof Array.prototype.toSpliced : function
toSpliced
ist splice, das eine Kopie zurückgibt. ES2023 — in aktuellen Laufzeiten also
vorhanden, aber nicht in dem, was du unterstützen sollst.
Objekte vergleichen sich über die Identität
filter(o => o !== {id:2}) : 2 items <- nothing removed
filter(o => o.id !== 2) : [ { id: 1 } ]
Zwei Objekte mit gleichem Inhalt sind nicht ===. Ein Objekt zu entfernen heißt
entweder, ein Feld zu vergleichen, oder die ursprüngliche Referenz zu haben.
Entfernen beim Vorwärtsiterieren überspringt Elemente
forwards : [ 'a', 'b', 'c' ] <- one 'b' survived
backwards : [ 'a', 'c' ]
Ein splice an Index i rückt alles dahinter um eins nach vorn, das nächste
Element rutscht also genau auf den Platz, den die Schleife gerade verlassen hat.
Rückwärts iterieren, oder filter nehmen.
Und für die Enden braucht es nichts von alledem:
pop() : b leaving [ 'a', 'b', 'c' ]
shift() : a leaving [ 'b', 'c' ]
Hinweis zu Netcup (Werbung)
Der deutsche Hoster Netcup bietet unter anderem günstige und zugleich leistungsstarke Webhosting Pakete, KVM-basierte Root Server und dezidierte Server an. Mit unseren Gutscheincodes kannst du noch mehr Geld sparen (6€ bei deiner ersten Bestellung, 30% Rabatt auf alle KVM-basierten Root Server, ...).