Zum Inhalt
wannacode

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);
Ausgabe
Brot
undefined
Kaffee
Butter
4
Jetzt muss jede Schleife über den Warenkorb undefined ü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}`);
Ausgabe
[ 'Brot', 'Kaffee', 'Butter' ]
Artikel: 3
  • push hängt hinten an.
  • Eine Methode, die nach Wert entfernt, gibt es nicht. indexOf findet den Index von „Milch“, und splice(index, 1) entfernt dort ein Element und schließt die Lücke: „Kaffee“ rückt auf den Platz von „Milch“.
  • length ist die Zahl der Elemente gerade jetzt.
  • console.log gibt 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
  1. cart zeigt auf ein Array. Darin liegen length und ein eigenes Array elements mit 3 Plätzen.
  2. Die Artikel aus dem Code füllen die Plätze nacheinander. Das Array ist voll: 3 von 3.
  3. Es ist kein Platz mehr. push legt ein Array mit 22 Plätzen an und kopiert die Elemente hinein.
  4. elements zeigt jetzt auf das neue Array, das alte braucht niemand mehr. „Butter“ kommt auf den freien Platz.
  5. splice entfernt „Milch“, und alles danach rückt einen Platz nach links. Es bleibt keine Lücke.
  6. 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, und length bleibt gleich:
const cart = ["Brot", "Milch", "Kaffee"];
delete cart[1];
console.log(cart, cart.length);
Ausgabe
[ 'Brot', <1 empty item>, 'Kaffee' ] 3

Fü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);
Ausgabe
[ '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"));
Ausgabe
Rechnung März
Kaffee mit dem Team, Rechnung März, Termin bei der Bank, Lagerbericht
3
false
  • tasks[i] liest, und tasks[i] = x ersetzt.
  • splice(i, 0, x) fügt bei Index i ein und schiebt den Rest nach rechts. Die Null bedeutet „nichts entfernen“.
  • indexOf(x) sucht und gibt den Index oder -1 zurück, und includes(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"));
Ausgabe
undefined
Lagerbericht
-1
  • includes und indexOf vergleichen 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);
Antwort

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]}`);
}
Ausgabe
- Brot
- Kaffee
- Butter
1. Brot
2. Kaffee
3. Butter
Genauer, für Neugierige
  • Entferne keine Elemente aus einem Array, während du es mit for...of durchlä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);
Ausgabe
[ '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);
Ausgabe
[ 'Milch' ]
Im Modul „Modernes JavaScript“ siehst du einen kürzeren Weg, der ein neues Array nur mit den gewünschten Elementen erzeugt: 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}`);
Ausgabe
Durchschnitt: 80

JavaScript 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));
Ausgabe
true
false

new 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.

Genauer, für Neugierige
const seats = [12, 7, 5];
seats.splice(seats.indexOf(2), 1);
console.log(seats);
Ausgabe
[ 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);
Ausgabe
[ '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");
Fehler
TypeError: Cannot add property 3, object is not extensible

const 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);
Ausgabe
[ '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);
Ausgabe
[ 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

Löse die Aufgaben in deinem Editor. Das Array ist ein privates Feld der Klasse (#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.

Ausgabe
Genommen: Unter dem Joch
2 ü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.

Ausgabe
2026-03-31 Bericht erstes Quartal
2026-05-20 Neuer Kaffeelieferant

3. 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.

Ausgabe
Collections: das Array wächst von selbst
Gelöscht: OOP
Notizen: 2
Es 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.

Eingabe
4
12
7
Ausgabe
2 + 2 = Richtig!
3 * 4 = Richtig!
15 - 9 = Falsch, die Antwort ist 6.
Ergebnis: 2 von 3

Weitere 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, list und end und halte die Liste zwischen ihnen. Der Befehl, einen Artikel zu entfernen, der nicht darin ist, sagt „Kein solcher Artikel.“

Test

Teste dich

1. Warum sind push und splice praktischer als das Schreiben per Index?
2. Was gibt console.log([30, 5, 12].sort()) aus?
3. seats ist [12, 2, 7, 5]. Was bleibt nach seats.splice(2, 1)?
4. tasks hat 3 Aufgaben. Was gibt console.log(tasks[3]) aus?
5. const days = Object.freeze(["Mo", "Di"]); Was passiert bei days.push("Mi")?

Erstellt von Ivo Gergov im Rahmen der Kampagne von Evo Tech für zugängliche Programmierausbildung ·