Arrays: push, splice und sort
Kurz gesagt: Ein Array ist in JavaScript auch eine Liste: push hängt hinten an, splice entfernt Elemente, ohne Lücken zu lassen, und sort sortiert es, Zahlen aber wie Text, wenn du keine Funktion übergibst.
Problem
Der Warenkorb ist voll
Du schreibst den Warenkorb eines Onlineshops und hältst die Artikel in einem Array, wie in der Lektion über Arrays: jeder Artikel an seinem Index. JavaScript lässt dich auch über das Ende hinaus schreiben, aber du musst dir den ersten freien Index merken. Und nimmt der Kunde einen Artikel heraus, bleibt eine Lücke:
const cart = ["Brot", "Milch", "Kaffee"];
// Ein vierter Artikel: Wir schreiben an den ersten freien Index.cart[cart.length] = "Butter";
// Der Kunde nimmt die Milch heraus.cart[1] = undefined;
for (const item of cart) { console.log(item);}console.log(cart.length);BrotundefinedKaffeeButter4undefined überspringen. Und die Zahl der Artikel ist nicht mehr cart.length: Das ist 4, aber es sind 3 Artikel.Das ist viel Code für etwas, das jeder Shop ständig macht.
Die Idee
push und splice: Das Array kümmert sich selbst
Das Array hat Methoden, die das für dich erledigen. Das Kopieren und Verschieben macht es selbst. Eine Collection, die so wächst und schrumpft, heißt Liste, und in JavaScript ist das das Array selbst:
const cart = [];cart.push("Brot");cart.push("Milch");cart.push("Kaffee");cart.push("Butter");cart.splice(cart.indexOf("Milch"), 1);console.log(cart);console.log(`Artikel: ${cart.length}`);[ 'Brot', 'Kaffee', 'Butter' ]Artikel: 3pushhängt hinten an.- Eine Methode, die nach Wert entfernt, gibt es nicht.
indexOffindet den Index von „Milch“, undsplice(index, 1)entfernt dort ein Element und schließt die Lücke: „Kaffee“ rückt auf den Platz von „Milch“. lengthist die Zahl der Elemente gerade jetzt.console.loggibt das ganze Array in eckigen Klammern aus, den Text in Anführungszeichen.
So sieht es im Array aus. Wie viele Plätze es hat, wählst nicht du. Das macht die Engine, die den Code ausführt (V8 in Node und Chrome). Ein Array mit 3 Artikeln, das im Code steht, hat genau 3 Plätze, also ist es beim vierten voll:
const cart = ["Brot", "Milch", "Kaffee"];cart.push("Butter");cart.splice(cart.indexOf("Milch"), 1);console.log(cart);console.log(`Artikel: ${cart.length}`);Schritt für Schritt, in Worten
- cart zeigt auf ein Array. Darin liegen length und ein eigenes Array elements mit 3 Plätzen.
- Die Artikel aus dem Code füllen die Plätze nacheinander. Das Array ist voll: 3 von 3.
- Es ist kein Platz mehr. push legt ein Array mit 22 Plätzen an und kopiert die Elemente hinein.
- elements zeigt jetzt auf das neue Array, das alte braucht niemand mehr. „Butter“ kommt auf den freien Platz.
- splice entfernt „Milch“, und alles danach rückt einen Platz nach links. Es bleibt keine Lücke.
- Von außen siehst du nur ein Array mit drei Artikeln. Wie viele Plätze es innen hat, entscheidet die Engine V8: Die Sprache verspricht es nicht.
Genauer, für Neugierige
- Es gibt auch
delete cart[1], aber das verschiebt nichts. Es lässt eine Lücke, undlengthbleibt gleich:
const cart = ["Brot", "Milch", "Kaffee"];delete cart[1];console.log(cart, cart.length);[ 'Brot', <1 empty item>, 'Kaffee' ] 3Für ein Array nimmst du splice.
Die Idee
Was in ein Array passt
Ein Array fragt nicht, was du hineinlegst. Text und eine Zahl können nebeneinander stehen:
const cart = [];cart.push("Brot");cart.push(5);console.log(cart);[ 'Brot', 5 ]Das sieht praktisch aus, aber der Fehler zeigt sich später, dort, wo du Text erwartest. Ein Array hält also eine Art von Dingen: nur Artikel, nur Preise.
JavaScript selbst kann nicht sagen „ein Array nur mit Text“. Das kann TypeScript. Es ist JavaScript mit Typen: Dort ist ein Array mit Text string[], und cart.push(5) ist schon im Editor ein Fehler.
Die Idee
Indizes: [i], splice, indexOf, includes
Ein Array hat Indizes von 0 bis tasks.length - 1. Du liest und ersetzt mit [ ], und du fügst mit splice ein:
const tasks = ["Rechnung März", "Bank anrufen", "Lagerbericht"];
console.log(tasks[0]);tasks[1] = "Termin bei der Bank";tasks.splice(0, 0, "Kaffee mit dem Team");console.log(tasks.join(", "));console.log(tasks.indexOf("Lagerbericht"));console.log(tasks.includes("Bank anrufen"));Rechnung MärzKaffee mit dem Team, Rechnung März, Termin bei der Bank, Lagerbericht3falsetasks[i]liest, undtasks[i] = xersetzt.splice(i, 0, x)fügt bei Indexiein und schiebt den Rest nach rechts. Die Null bedeutet „nichts entfernen“.indexOf(x)sucht und gibt den Index oder-1zurück, undincludes(x)sagt nur, ob es darin ist.join(", ")verbindet die Elemente zu einem Text, getrennt durch Kommas.
Genauer, für Neugierige
- Ein Index außerhalb des Arrays bricht das Programm nicht ab. Er gibt
undefined.at(-1)zählt von hinten und gibt das letzte Element:
const tasks = ["Rechnung März", "Bank anrufen", "Lagerbericht"];console.log(tasks[3]);console.log(tasks.at(-1));console.log(tasks.indexOf("Gehälter"));undefinedLagerbericht-1includesundindexOfvergleichen mit===. Text ist ein Wert, darum finden sie gleichen Text.- Einfügen und Entfernen vorne sind in einem großen Array langsam: Jedes Element nach dem Index rückt einen Platz weiter. Bei einer Million Elementen sind das eine Million Verschiebungen.
Probier es aus
Wer ist dran?
Die Liste der Patienten, die beim Arzt warten. Jonas geht hinein, und Anna hat einen Termin, darum bekommt sie den zweiten Platz.
Was gibt das Programm aus?
const waiting = ["Jonas", "Maria", "Peter"];waiting.shift();waiting.splice(1, 0, "Anna");console.log(waiting, waiting.length);shift() entfernt Jonas, und Maria wird Erste, bei Index 0. splice(1, 0, "Anna") fügt Anna bei Index 1 ein und schiebt Peter nach rechts. Drei bleiben übrig.
shift() entfernt das erste Element, wie splice(0, 1).
Die Idee
Die Elemente durchlaufen
Ein Array durchläufst du mit for...of, wenn du nur die Elemente brauchst, oder mit einem Index, wenn du auch die Nummer brauchst:
const cart = ["Brot", "Kaffee", "Butter"];
for (const item of cart) { console.log(`- ${item}`);}for (let i = 0; i < cart.length; i++) { console.log(`${i + 1}. ${cart[i]}`);}- Brot- Kaffee- Butter1. Brot2. Kaffee3. ButterGenauer, für Neugierige
- Entferne keine Elemente aus einem Array, während du es mit
for...ofdurchläufst. Das Programm bricht nicht ab, aber es überspringt Elemente:
const cart = ["Brot", "Brot", "Milch"];for (const item of cart) { if (item === "Brot") { cart.splice(cart.indexOf(item), 1); }}console.log(cart);[ 'Brot', 'Milch' ]Das zweite „Brot“ ist geblieben. splice hat alles nach links verschoben, und die Schleife ging beim nächsten Index weiter und hat es nie gesehen. Es gibt keinen Fehler, darum ist so ein Versäumnis schwer zu finden.
- Wenn du entfernen musst, durchläufst du mit einem Index von hinten nach vorne. So verschiebt das Entfernen nicht die Elemente, die du noch nicht geprüft hast:
const cart = ["Brot", "Brot", "Milch"];for (let i = cart.length - 1; i >= 0; i--) { if (cart[i] === "Brot") { cart.splice(i, 1); }}console.log(cart);[ 'Milch' ]filter.Die Idee
Zahlen in einem Array
Ein Array mit Noten ist wie ein Array mit Text. Die Zahl liegt so im Array, wie sie ist:
const scores = [85, 64, 91];
let total = 0;for (const score of scores) { total += score;}console.log(`Durchschnitt: ${total / scores.length}`);Durchschnitt: 80JavaScript gibt 80 aus, nicht 80.0: Ganze Zahlen und Kommazahlen sind für es derselbe Typ, number.
Genauer, für Neugierige
- Eine Zahl ist in JavaScript ein primitiver Wert, kein Objekt. Darum vergleicht
===die Werte, und zwei gleiche Zahlen sind gleich. Es gibt auch eine Hülle,new Number(257), die ein Objekt erzeugt, und zwei Objekte sind verschieden, auch wenn sie dasselbe enthalten:
const c = Number("257");const d = Number("257");console.log(c === d);console.log(new Number(257) === new Number(257));truefalsenew Number brauchst du nicht. Schreib die Zahlen direkt.
Probier es aus
Finde den Fehler
Ein Theater hält die belegten Plätze in einer Array. Ein Kunde gibt Platz 2 zurück, und das Programm soll [ 12, 7, 5 ] ausgeben. Stattdessen gibt es [ 12, 2, 5 ] aus. In welcher Zeile steckt der Fehler?
Wähle die Zeile mit dem Fehler.
splice(2, 1) entfernt ein Element ab Index 2, also Platz 7. Um den Wert 2 zu entfernen, such zuerst seinen Index: seats.splice(seats.indexOf(2), 1). Vorsicht, wenn der Wert nicht darin ist: indexOf gibt -1, und splice(-1, 1) entfernt das letzte Element. Prüf also zuerst mit includes.Genauer, für Neugierige
const seats = [12, 7, 5];seats.splice(seats.indexOf(2), 1);console.log(seats);[ 12, 7 ]Die Idee
Sortieren und ein Array, das sich nicht ändert
sort() sortiert das Array an Ort und Stelle. Text kommt alphabetisch heraus. Aber Zahlen kommen nicht nach Größe heraus:
const cities = ["Hamburg", "Berlin", "Dresden"];cities.sort();console.log(cities);
const prices = [30, 5, 12];prices.sort();console.log(prices);prices.sort(function (a, b) { return a - b;});console.log(prices);[ 'Berlin', 'Dresden', 'Hamburg' ][ 12, 30, 5 ][ 5, 12, 30 ]Ohne Regel macht sort aus allem Text und vergleicht den Text. „12“ kommt vor „30“ und „30“ vor „5“, wie in einem Wörterbuch. Darum gibst du Zahlen eine Regel: eine Funktion, die zwei Zahlen bekommt und a - b zurückgibt. Ein negatives Ergebnis bedeutet „a kommt vor b“. Schreib sie vorerst ab. In der Lektion „Klassen in Klassen“ siehst du, wie man solche Regeln schreibt.
Ein Array, das sich nicht ändert, erzeugst du mit Object.freeze. Es ist unveränderlich: Du kannst darin nichts hinzufügen, entfernen oder sortieren.
const days = Object.freeze(["Mo", "Di", "Mi"]);days.push("Do");TypeError: Cannot add property 3, object is not extensibleconst reicht dafür nicht: Es verhindert nur, dass days auf ein anderes Array zeigt, das Array selbst kann sich weiter ändern.
Genauer, für Neugierige
- Text wird nach den Codes seiner Zeichen sortiert. Großbuchstaben kommen vor Kleinbuchstaben, darum kommt „Traube“ vor „apfel“:
const fruit = ["apfel", "Birne", "banane", "Traube"];fruit.sort();console.log(fruit);[ 'Birne', 'Traube', 'apfel', 'banane' ]toSorted()gibt ein neues, sortiertes Array zurück und rührt das alte nicht an:
const prices = [30, 5, 12];const cheapFirst = prices.toSorted(function (a, b) { return a - b;});console.log(cheapFirst, prices);[ 5, 12, 30 ] [ 30, 5, 12 ]- Wie du eigene Objekte sortierst, zum Beispiel Produkte nach Preis, siehst du in der Lektion „Klassen in Klassen“.
Übung
Arrays in Klassen
#books), und der Code unter den Klassen ruft nur ihre Methoden auf.1. Ein Bücherregal. Eine Klasse BookShelf mit einer Methode addBook(title), die das Buch ans Ende stellt, und takeBook(), die das erste Buch zurückgibt und entfernt (oder null, wenn das Regal leer ist). Füge count() und toString() hinzu. Füge „Unter dem Joch“, „Tabak“ und „Der eiserne Leuchter“ hinzu, nimm ein Buch und gib den Rest aus.
Genommen: Unter dem Joch2 übrig: [Tabak, Der eiserne Leuchter]2. Ein Ereignisprotokoll. Eine Klasse Event mit einem Datum und einer Beschreibung und eine Klasse EventLog mit den Methoden addEvent(date, description) und getEventsBetween(from, to), die eine Array der Ereignisse zwischen den beiden Daten zurückgibt, einschließlich. Die Daten sind Text in der Form 2026-03-31. In dieser Form sortiert sich der Text genauso wie die Daten, darum vergleichen <= und >= sie richtig. Füge vier Ereignisse hinzu: 2026-01-15 „Jahresinventur“, 2026-03-31 „Bericht erstes Quartal“, 2026-05-20 „Neuer Kaffeelieferant“, 2026-09-01 „Neues Schuljahr“. Gib die vom 2026-03-01 bis 2026-06-30 aus.
2026-03-31 Bericht erstes Quartal2026-05-20 Neuer Kaffeelieferant3. Ein Notizbuch. Eine Klasse Note mit einem Titel und einem Inhalt und eine Klasse Notebook mit den Methoden addNote, findNote(title) (gibt die Notiz oder null zurück), deleteNote(title) (gibt true zurück, wenn es etwas gelöscht hat) und count(). Füge die Notizen „OOP“, „Collections“ und „SQL“ hinzu, finde „Collections“, lösche „OOP“ und prüfe, dass sie weg ist.
Collections: das Array wächst von selbstGelöscht: OOPNotizen: 2Es gibt keine Notiz OOP.4. Kopfrechnen. Eine Klasse Question mit einem Text und der richtigen Antwort und eine Klasse MathGame mit einer Array von Fragen, einer Methode addQuestion und einer Methode start(). start stellt die Fragen nacheinander, liest die Antwort und sagt am Ende, wie viele richtig waren. Die Fragen sind 2 + 2, 3 * 4 und 15 - 9.
start liest mit ask aus der Lektion über die Eingabe, darum ist es async start(), und der Aufruf ist await game.start(). Eine Methode, die auf Eingabe wartet, schreibt man so. Schreib es vorerst ab.
41272 + 2 = Richtig!3 * 4 = Richtig!15 - 9 = Falsch, die Antwort ist 6.Ergebnis: 2 von 3Weitere Aufgaben
- Keine Wiederholungen. Lies 6 Namen ein und sammle sie in einer Array, wobei du die überspringst, die schon darin sind. Für die Eingabe Jonas, Maria, Jonas, Anna, Maria, Peter ist die Ausgabe
[ 'Jonas', 'Maria', 'Anna', 'Peter' ]. - Der teuerste Artikel. Eine Array enthält Preise. Finde den höchsten und seinen Index, ohne
Math.max. - Die Liste umdrehen. Schreib eine Funktion, die eine neues Array mit denselben Elementen in umgekehrter Reihenfolge zurückgibt. Ändere das Original nicht.
- Eine Einkaufsliste. Lies die Befehle
add milk,remove milk,listundendund halte die Liste zwischen ihnen. Der Befehl, einen Artikel zu entfernen, der nicht darin ist, sagt „Kein solcher Artikel.“
Test
Teste dich
Verwandte Lektionen
Abschnitt „Verwandte Lektionen“- Baut auf: Polymorphie · Interfaces ohne interface · Exceptions · Strings
- Geht weiter in: Stack, Queue und verkettete Liste · Map und Set · Hashcodes und Hashfunktionen · Klassen und Daten in Klassen
- Aufgaben zum Thema: Collections