Array-Methoden in JavaScript: map, filter und reduce verstehen

map, filter und reduce sind die drei mächtigsten Werkzeuge für die Arbeit mit Arrays. Lerne, wie du damit Datenverarbeitung deklarativ und ohne fehleranfällige Schleifen schreibst.

Teilen

Sobald du in JavaScript mit Listen von Daten arbeitest, tauchen sie überall auf: map, filter und reduce. Diese drei Array-Methoden gehören zum Wichtigsten, was du für den Alltag als Entwickler lernen kannst. Statt eine for-Schleife zu schreiben, einen Zähler hochzuzählen und Elemente manuell in ein neues Array zu schieben, beschreibst du einfach was passieren soll – nicht das mühsame wie. In diesem Beitrag schauen wir uns die drei Methoden Schritt für Schritt an und kombinieren sie am Ende zu einer echten Datenpipeline.

Warum überhaupt Array-Methoden?

Stell dir vor, du willst aus einer Liste von Zahlen die doppelten Werte berechnen. Der klassische Weg mit einer Schleife sieht so aus:

const zahlen = [1, 2, 3, 4];
const verdoppelt = [];

for (let i = 0; i < zahlen.length; i++) {
  verdoppelt.push(zahlen[i] * 2);
}

console.log(verdoppelt); // [2, 4, 6, 8]

Das funktioniert, aber es gibt viel Boilerplate: ein leeres Array, ein Zählindex, eine Abbruchbedingung. Jede dieser Zeilen ist eine potenzielle Fehlerquelle. Array-Methoden nehmen dir genau diese Arbeit ab und machen deine Absicht auf einen Blick lesbar. Wichtig: map und filter verändern das ursprüngliche Array nie, sondern geben immer ein neues Array zurück.

map: Jedes Element umwandeln

Die Methode map geht jedes Element durch und wendet eine Funktion darauf an. Das Ergebnis ist ein neues Array mit genau gleich vielen Elementen. Das Beispiel von oben wird damit zum Einzeiler:

const zahlen = [1, 2, 3, 4];
const verdoppelt = zahlen.map(zahl => zahl * 2);

console.log(verdoppelt); // [2, 4, 6, 8]
console.log(zahlen);     // [1, 2, 3, 4] – unverändert

Besonders nützlich ist map, wenn du Objekte umformen willst – etwa aus einer Liste von Benutzern nur die Namen ziehen:

const benutzer = [
  { id: 1, name: "Anna" },
  { id: 2, name: "Ben" },
  { id: 3, name: "Clara" },
];

const namen = benutzer.map(b => b.name);
console.log(namen); // ["Anna", "Ben", "Clara"]

filter: Elemente aussortieren

Während map jedes Element umwandelt, entscheidet filter nur, ob ein Element behalten wird. Die übergebene Funktion muss true oder false zurückgeben. Alle Elemente, für die sie true liefert, landen im neuen Array:

const zahlen = [1, 2, 3, 4, 5, 6];
const geradeZahlen = zahlen.filter(zahl => zahl % 2 === 0);

console.log(geradeZahlen); // [2, 4, 6]

Das Ergebnis kann also kürzer sein als das Original. Ein häufiger Anwendungsfall ist das Herausfiltern nach einer Bedingung, zum Beispiel nur aktive Benutzer:

const benutzer = [
  { name: "Anna", aktiv: true },
  { name: "Ben", aktiv: false },
  { name: "Clara", aktiv: true },
];

const aktive = benutzer.filter(b => b.aktiv);
console.log(aktive.length); // 2

reduce: Alles zu einem Wert zusammenfassen

Die dritte Methode ist die vielseitigste und wirkt anfangs am kompliziertesten. reduce nimmt ein Array und dampft es zu einem einzigen Wert ein – das kann eine Zahl, ein String, aber auch ein Objekt sein. Sie bekommt zwei Argumente: eine Funktion und einen Startwert. Die Funktion erhält den bisher aufgelaufenen Wert (den akku, kurz für Akkumulator) und das aktuelle Element:

const zahlen = [10, 20, 30, 40];

const summe = zahlen.reduce((akku, zahl) => akku + zahl, 0);
console.log(summe); // 100

Der Startwert 0 ist wichtig: Er legt fest, womit der Akkumulator beginnt. Bei jedem Durchlauf gibst du den neuen Wert des Akkumulators zurück. reduce kann weit mehr als summieren – hier zählen wir zum Beispiel, wie oft jedes Wort vorkommt:

const woerter = ["apfel", "birne", "apfel", "kirsche", "birne", "apfel"];

const anzahl = woerter.reduce((akku, wort) => {
  akku[wort] = (akku[wort] || 0) + 1;
  return akku;
}, {});

console.log(anzahl); // { apfel: 3, birne: 2, kirsche: 1 }

Die drei Methoden verketten

Ihre wahre Stärke spielen die Methoden aus, wenn du sie hintereinander aufrufst. Da map und filter jeweils ein neues Array zurückgeben, kannst du direkt die nächste Methode daran hängen. So entsteht eine gut lesbare Pipeline, die von oben nach unten erzählt, was mit den Daten passiert:

const bestellungen = [
  { produkt: "Buch", preis: 15, bezahlt: true },
  { produkt: "Stift", preis: 3, bezahlt: false },
  { produkt: "Lampe", preis: 40, bezahlt: true },
  { produkt: "Tasse", preis: 8, bezahlt: true },
];

const gesamtMitRabatt = bestellungen
  .filter(b => b.bezahlt)          // nur bezahlte behalten
  .map(b => b.preis * 0.9)         // 10 % Rabatt anwenden
  .reduce((summe, preis) => summe + preis, 0);

console.log(gesamtMitRabatt); // 56.7

Lies die Kette wie einen Satz: Nimm die bezahlten Bestellungen, ziehe 10 Prozent ab und addiere die Beträge. Genau diese Lesbarkeit macht funktionale Array-Methoden so beliebt. Ein Hinweis zur Performance: Jede Methode läuft einmal komplett durch das Array. Bei sehr großen Datenmengen kann eine einzelne Schleife schneller sein – für die allermeisten Fälle ist die Verkettung aber völlig ausreichend und deutlich wartbarer.

Fazit

Mit map, filter und reduce hast du drei Werkzeuge, die zusammen fast jede Datenverarbeitung abdecken: map wandelt um, filter sortiert aus, reduce fasst zusammen. Sie verändern das Original nie und lassen sich elegant verketten. Übe sie am besten an eigenen Daten – ersetze in deinem nächsten Projekt eine for-Schleife durch die passende Array-Methode. Du wirst schnell merken, wie viel klarer dein Code dadurch wird.