Array-Duplikat: Warum diese Aufgabe tausende Aufrufe auf Stack Overflow gesammelt hat
\n\nStellen Sie sich vor: Sie schreiben einen Online-Shop, ein Benutzer fügt Produkte zum Warenkorb hinzu. Aber aufgrund eines Fehlers oder Bugs erscheint dasselbe iPhone dreimal in der Liste. Oder Sie parsen eine Liste von Tags aus einer Datenbank, und "JavaScript" kommt 15 Mal hintereinander vor. Was tun? Richtig – nur die einzigartigen Werte behalten.
\n\nDie Frage "Get all unique values in a JavaScript array (remove duplicates)" auf Stack Overflow hat hunderttausende Aufrufe gesammelt. Und das ist kein Zufall. Die Aufgabe scheint einfach, aber unter der Haube verbirgt sich ein ganzes Arsenal an Ansätzen: von Einzeilern im modernen ES6 bis hin zu kniffligen Tricks mit filter und indexOf. In diesem Artikel geben wir nicht nur fertige Lösungen, sondern analysieren, wie jede einzelne auf der Ebene der JavaScript-Engine funktioniert.
Bereit, unter die Haube zu schauen? Los geht's!
\n\n\n\n
Methode Nr. 1: Set – der König der Leistung
\n\nDer eleganteste und schnellste Weg, einzigartige Werte in einem JavaScript-Array zu erhalten, ist die Verwendung des Set-Objekts. Es wurde in ES6 eingeführt und ist buchstäblich für diese Aufgabe gemacht.
const numbers = [1, 2, 2, 3, 4, 4, 5];\nconst uniqueNumbers = [...new Set(numbers)];\n\nconsole.log(uniqueNumbers); // [1, 2, 3, 4, 5]\n\nWie funktioniert das unter der Haube?
\nDas Set-Objekt speichert nur einzigartige Werte. Wenn wir das Array an den Konstruktor new Set(numbers) übergeben, durchläuft die JavaScript-Engine jedes Element und fügt es in eine interne Hash-Tabelle ein. Wenn der Wert bereits vorhanden ist, wird er ignoriert. Anschließend wandelt der Spread-Operator ... das Set zurück in ein Array.
Warum ist das schnell? Weil die Suche und das Einfügen in einem Set in O(1) (konstanter Zeit) erfolgen. Bei einem Array mit 10.000 Elementen wird der Unterschied zu anderen Methoden enorm sein.
\n\nWichtig: Set behält die Reihenfolge der Elemente bei, funktioniert aber nur mit Primitiven (Zahlen, Strings, boolesche Werte). Bei Objekten erfolgt der Vergleich per Referenz, nicht nach Inhalt.
\n\nWann verwenden?
\n- \n
- Wenn das Array aus Zahlen oder Strings besteht. \n
- Wenn die Verarbeitungsgeschwindigkeit großer Arrays wichtig ist. \n
- Wenn Sie modernen Code schreiben und keine Angst vor ES6 haben. \n
\n\n
Methode Nr. 2: filter + indexOf – der Klassiker
\n\nDiese Methode ist ein Veteran in JavaScript. Sie funktioniert in allen Browsern ohne Polyfills und ist auf Stack Overflow immer noch beliebt.
\n\nconst numbers = [1, 2, 2, 3, 4, 4, 5];\nconst uniqueNumbers = numbers.filter((value, index, arr) => {\n return arr.indexOf(value) === index;\n});\n\nconsole.log(uniqueNumbers); // [1, 2, 3, 4, 5]\n\nLogik erklärt
\nDie Methode filter erstellt ein neues Array und behält nur die Elemente, für die der Callback true zurückgibt. Innerhalb des Callbacks prüfen wir: Ist der aktuelle Index das erste Vorkommen dieses Werts im Array? Wenn ja, behalten wir das Element. Wenn der Wert bereits früher vorgekommen ist, gibt indexOf einen kleineren Index zurück, die Bedingung wird nicht erfüllt, und das Duplikat wird verworfen.
Der Haken: indexOf durchläuft jedes Mal das Array von Anfang an. Dies ergibt eine Komplexität von O(n²). Bei kleinen Arrays (bis zu 1000 Elementen) ist der Unterschied nicht spürbar, aber bei 100.000 Elementen kann der Browser für eine Sekunde einfrieren.
Wann verwenden?
\n- \n
- Wenn Sie alte Browser (IE11) unterstützen müssen. \n
- Wenn das Array klein ist. \n
- Wenn Sie die Logik des "ersten Vorkommens" anschaulich darstellen möchten. \n
\n\n
Methode Nr. 3: reduce + Akkumulator – Flexibilität und Kontrolle
\n\nDie Methode reduce gibt Ihnen die volle Kontrolle über den Prozess. Wir entscheiden selbst, wie das Ergebnis gesammelt wird.
const numbers = [1, 2, 2, 3, 4, 4, 5];\nconst uniqueNumbers = numbers.reduce((acc, value) => {\n if (!acc.includes(value)) {\n acc.push