Zum Inhalt springen
aviral gupta

// B5.2 · ca. 30 Min. · Einstieg

map, filter und reduce

Nach dieser Lektion wandeln Sie Arrays mit map, filter und reduce um, wählen aus, summieren, verketten die Methoden und meiden ihre klassischen Fallen.

Lektion 2 von 5 in B5 Arrays, Objekte und JSON

Danach können Sie

  • Einen Callback mit (value, index) schreiben, mit map ein neues Array bilden und mit filter Elemente behalten
  • Ein Array mit reduce und einem Startwert summieren und den TypeError bei einem leeren Array ohne Startwert erklären
  • Die Methoden verketten, some und every nutzen und zwischen forEach und map wählen
  1. Aufwärmen · Aufgabe 1 von 7

    Zum Aufwärmen: Was gibt dieser Code aus?

    console.log([1, 2, 3].map((n) => n * 10));
  2. Vorhersagen · Aufgabe 2 von 7

    Sagen Sie es vorher, bevor Sie weiterlesen: Was gibt dieser Code aus?

    const nums = [5, 12, 8, 20];
    console.log(nums.filter((n) => n > 10), nums);
  3. Üben · Aufgabe 3 von 7

    Ergänzen Sie den Startwert so, dass reduce die Zahlen addiert und das Programm 9 ausgibt.

    console.log([2, 3, 4].reduce((sum, n) => sum + n, ____));
    console.log([2, 3, 4].reduce((sum, n) => sum + n, ));
  4. Üben · Aufgabe 4 von 7

    Ordnen Sie jedem Aufruf auf nums = [1, 2, 3] zu, was er zurückgibt.

  5. Üben · Aufgabe 5 von 7

    Der Callback hat einen zweiten Parameter. Was gibt dieser Code aus?

    console.log(["a", "b", "c"].map((letter, i) => letter + i));
  6. Denksport · Aufgabe 6 von 7

    Knobelaufgabe. parseInt("2") ist 2. Was gibt also dieser Code aus?

    console.log(["1", "2", "3"].map(parseInt));
  7. Anwenden · Aufgabe 7 von 7

    Kleine Aufgabe: eine Notenliste. Beginnen Sie mit fünf Punktzahlen von 100. Erzeugen Sie mit map und dem Index ein Label pro Person, etwa 1: pass oder 2: fail (ab 50 bestanden), und geben Sie sie mit ", " verbunden aus. Zählen Sie mit filter, wie viele bestanden haben, berechnen Sie mit reduce und einem Startwert den Durchschnitt und geben Sie beides aus. Geben Sie zum Schluss aus, ob eine Punktzahl 90 oder mehr ist und ob alle bestanden haben.

    Prüfen Sie Ihr Ergebnis anhand dieser Liste

Selbst programmieren

Lesen Sie das ausgearbeitete Beispiel und lösen Sie dann die Übungen. Ihr Code läuft in Ihrem Browser oder auf Ihrem Computer und wird nie hochgeladen.

Ausgearbeitetes Beispiel

Eine Woche Schrittzahlen

Fünf Tage Schrittzahlen, bearbeitet mit den Methoden dieser Lektion: map macht daraus Tausender und Labels, filter behält die Tage mit mindestens 10.000 Schritten, reduce summiert die Woche, some und every beantworten Ja/Nein-Fragen, und der letzte Teil verkettet filter mit reduce. Die letzte Zeile zeigt, dass steps selbst sich nie geändert hat.

main.js

// Step counts for one working week: transform, select, total.
const steps = [4200, 11800, 7600, 12500, 9100];

const inThousands = steps.map((n) => Math.round(n / 1000));
console.log(inThousands);

const labels = steps.map((n, i) => `Day ${i + 1}: ${n}`);
console.log(labels[0], "|", labels.at(-1));

const goalDays = steps.filter((n) => n >= 10000);
console.log(goalDays, goalDays.length);

const total = steps.reduce((sum, n) => sum + n, 0);
console.log(total, total / steps.length);

console.log(steps.some((n) => n < 5000), steps.every((n) => n > 5000));

const goalTotal = steps.filter((n) => n >= 10000).reduce((sum, n) => sum + n, 0);
console.log(goalTotal, steps);

Ausführen mit

node main.js

Ausgabe

[ 4, 12, 8, 13, 9 ]
Day 1: 4200 | Day 5: 9100
[ 11800, 12500 ] 2
45200 9040
true false
24300 [ 4200, 11800, 7600, 12500, 9100 ]
  • map gibt so viele Elemente zurück, wie es erhält: fünf Zahlen, fünf gerundete Zahlen.
  • Die Labels nutzen den Index i, der bei 0 beginnt, also ist der erste Tag i + 1.
  • reduce beginnt beim Startwert 0 und addiert jede Zahl zu sum.
  • some ist true, weil ein Tag unter 5000 liegt; every ist aus demselben Grund false.
  • Die Kette filtert zuerst und summiert dann nur die Tage mit erreichtem Ziel.
Ändern und ausführen

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser den JavaScript-Runner herunter (bis zu 0.1 MB) und speichert ihn im Cache. Ihr Code läuft in der eigenen Engine Ihres Browsers und bleibt auf Ihrem Gerät.

Übungen

Übung 1 von 2

map oder forEach, filter oder map

squares(nums) soll ein neues Array mit jeder Zahl im Quadrat zurückgeben, passed(scores) ein neues Array nur mit den Punktzahlen ab 50. Der Starter wählt in beiden Funktionen die falsche Methode: Eine gibt undefined zurück, die andere ein Array aus true und false. Beheben Sie beide mit der richtigen Methode. Lassen Sie das Wort export vor jeder Funktion stehen.

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser den JavaScript-Runner herunter (bis zu 0.1 MB) und speichert ihn im Cache. Ihr Code läuft in der eigenen Engine Ihres Browsers und bleibt auf Ihrem Gerät.

Hinweise
  1. Hinweis 1

    Führen Sie die Tests aus: squares gibt undefined zurück. Was gibt forEach immer zurück?

  2. Hinweis 2

    Nehmen Sie map, wenn Sie pro altem Element ein neues wollen: nums.map((n) => n * n).

  3. Hinweis 3

    passed gibt [true, false, …] zurück, weil map behält, was der Callback zurückgibt. Welche Methode behält die Elemente, für die der Callback true ist?

Eine Lösung zeigen

Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.

// Return a new array with every number squared.
export function squares(nums) {
  return nums.map((n) => n * n);
}

// Return a new array with only the scores of 50 or more.
export function passed(scores) {
  return scores.filter((s) => s >= 50);
}
Auf dem eigenen Computer ausführen

Installieren Sie ECMAScript 2026 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.

main.js

// Return a new array with every number squared.
export function squares(nums) {
  return nums.forEach((n) => n * n);
}

// Return a new array with only the scores of 50 or more.
export function passed(scores) {
  return scores.map((s) => s >= 50);
}

main.test.js

import {test} from 'node:test';
import assert from 'node:assert/strict';
import {squares, passed} from './main.js';

test('squares([1, 2, 3]) gibt [1, 4, 9] zurück', () => {
  const got = squares([1, 2, 3]);
  assert.deepEqual(got, [1, 4, 9], `squares([1, 2, 3]) hat ${JSON.stringify(got)} zurückgegeben, erwartet [1,4,9]`);
});

test('squares lässt das übergebene Array unverändert', () => {
  const nums = [4, 5];
  squares(nums);
  assert.deepEqual(nums, [4, 5], `nach dem Aufruf war das Array ${JSON.stringify(nums)}, erwartet [4,5]`);
});

test('passed behält nur die Punktzahlen ab 50', () => {
  const got = passed([72, 45, 50, 38]);
  assert.deepEqual(got, [72, 50], `passed([72, 45, 50, 38]) hat ${JSON.stringify(got)} zurückgegeben, erwartet [72,50]`);
});

test('passed gibt ein leeres Array zurück, wenn niemand bestanden hat', () => {
  const got = passed([10, 20]);
  assert.deepEqual(got, [], `passed([10, 20]) hat ${JSON.stringify(got)} zurückgegeben, erwartet []`);
});

package.json

{
  "type": "module"
}

package.json sagt Node.js, dass die .js-Dateien Module sind; lassen Sie die Datei im Ordner.

Programm ausführen:

node main.js

Prüfungen ausführen (learnrun.js muss im selben Ordner liegen):

node --test
learnrun.js herunterladen

Übung 2 von 2

Summe der großen Bestellungen

bigOrdersTotal(orders, limit) soll die Bestellungen ab limit addieren und 0 zurückgeben, wenn es keine gibt. anyRefund(orders) soll true zurückgeben, wenn mindestens eine Bestellung negativ ist. Der Starter summiert richtig, solange einige Bestellungen groß genug sind, stoppt aber mit einem TypeError, wenn keine es ist, und anyRefund stellt die falsche Frage. Beheben Sie beides.

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser den JavaScript-Runner herunter (bis zu 0.1 MB) und speichert ihn im Cache. Ihr Code läuft in der eigenen Engine Ihres Browsers und bleibt auf Ihrem Gerät.

Hinweise
  1. Hinweis 1

    Führen Sie die Tests aus: Bei [5, 3] behält filter nichts. Was macht reduce mit einem leeren Array ohne Startwert?

  2. Hinweis 2

    Geben Sie reduce einen Startwert als zweites Argument: reduce((sum, o) => sum + o, 0).

  3. Hinweis 3

    every fragt „Sind alle Bestellungen negativ?“. Welche Methode fragt „Ist mindestens eine negativ?“

Eine Lösung zeigen

Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.

// Add up the orders of limit or more; 0 when there are none.
export function bigOrdersTotal(orders, limit) {
  return orders.filter((o) => o >= limit).reduce((sum, o) => sum + o, 0);
}

// true when at least one order is negative.
export function anyRefund(orders) {
  return orders.some((o) => o < 0);
}
Auf dem eigenen Computer ausführen

Installieren Sie ECMAScript 2026 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.

main.js

// Add up the orders of limit or more; 0 when there are none.
export function bigOrdersTotal(orders, limit) {
  return orders.filter((o) => o >= limit).reduce((sum, o) => sum + o);
}

// true when at least one order is negative.
export function anyRefund(orders) {
  return orders.every((o) => o < 0);
}

main.test.js

import {test} from 'node:test';
import assert from 'node:assert/strict';
import {bigOrdersTotal, anyRefund} from './main.js';

test('Addiert nur die Bestellungen ab 10', () => {
  const got = bigOrdersTotal([20, 5, 50, 10], 10);
  assert.equal(got, 80, `bigOrdersTotal([20, 5, 50, 10], 10) hat ${got} zurückgegeben, erwartet 80`);
});

test('Gibt 0 zurück, wenn keine Bestellung groß genug ist', () => {
  const got = bigOrdersTotal([5, 3], 10);
  assert.equal(got, 0, `bigOrdersTotal([5, 3], 10) hat ${got} zurückgegeben, erwartet 0`);
});

test('anyRefund findet eine negative Bestellung unter anderen', () => {
  const got = anyRefund([12, -4, 30]);
  assert.equal(got, true, `anyRefund([12, -4, 30]) hat ${got} zurückgegeben, erwartet true`);
});

test('anyRefund ist false, wenn keine Bestellung negativ ist', () => {
  const got = anyRefund([12, 30]);
  assert.equal(got, false, `anyRefund([12, 30]) hat ${got} zurückgegeben, erwartet false`);
});

package.json

{
  "type": "module"
}

package.json sagt Node.js, dass die .js-Dateien Module sind; lassen Sie die Datei im Ordner.

Programm ausführen:

node main.js

Prüfungen ausführen (learnrun.js muss im selben Ordner liegen):

node --test
learnrun.js herunterladen

Häufige Fehler

reduce auf einem leeren Array ohne Startwert

const prices = [];
const total = prices.reduce((sum, p) => sum + p);
console.log(total);

Was Node.js ausgibt

TypeError: Reduce of empty array with no initial value

Warum, und die Lösung

Ohne Startwert nimmt reduce das erste Element als Anfangssumme, und ein leeres Array hat kein erstes Element. Dasselbe passiert nach einem filter, der nichts behält. Übergeben Sie als zweites Argument einen Startwert, 0 für eine Summe: prices.reduce((sum, p) => sum + p, 0) gibt für ein leeres Array 0 zurück.

Geschweifte Klammern ohne return in map

const nums = [1.5, 2.25];
const doubled = nums.map((n) => {
  n * 2;
});
console.log(doubled[0].toFixed(1));

Was Node.js ausgibt

TypeError: Cannot read properties of undefined (reading 'toFixed')

Warum, und die Lösung

Eine Pfeilfunktion mit geschweiften Klammern gibt nur zurück, was eine return-Anweisung ihr gibt, wie Lektion B4.4 gezeigt hat. Hier berechnet der Callback n * 2 und wirft es weg, also baut map [ undefined, undefined ]. Schreiben Sie return n * 2; in die Klammern, oder lassen Sie die Klammern weg: nums.map((n) => n * 2).

Das Ergebnis von forEach verwenden

const names = ["ada", "linus"];
const upper = names.forEach((n) => n.toUpperCase());
console.log(upper.join(", "));

Was Node.js ausgibt

TypeError: Cannot read properties of undefined (reading 'join')

Warum, und die Lösung

forEach führt den Callback für jedes Element aus, gibt aber immer undefined zurück, also ist upper undefined und hat keine Methode join. Für ein neues Array mit Ergebnissen nehmen Sie map: names.map((n) => n.toUpperCase()). forEach bleibt für Nebenwirkungen, etwa um jedes Element auszugeben.

JavaScript im Browser: die eigene Engine Ihres Browsers in einem abgeschotteten Worker. Syntaxfehler findet acorn 8.18.0, MIT. Lizenz und Quellcode

Abschlussquiz

5 Fragen, ohne Hinweise. Ab 80 % ist die Lektion abgeschlossen.

Erledigen Sie zuerst alle Aufgaben oben, um das Abschlussquiz freizuschalten.

Problem melden

Etwas ist falsch oder unklar? Beschreiben Sie es kurz, dann wird es geprüft und korrigiert.

#

Mindestens 20 Zeichen.

Nur, wenn Sie eine Antwort wünschen.

Kernideen

Eine Funktion für jedes Element

map, filter, reduce, forEach, some und every nehmen jeweils eine Funktion, den Callback, und rufen sie einmal pro Element auf, wie find in Lektion B5.1. Der Callback erhält das Element und danach seinen Index: (value, index). Pfeilfunktionen aus B4.4 halten Callbacks kurz: (n) => n * 2. map baut aus den Rückgabewerten des Callbacks ein neues Array gleicher Länge: [1, 2, 3].map((n) => n * 10) ist [ 10, 20, 30 ]. filter behält die Elemente, für die der Callback, ein Prädikat, einen truthy Wert liefert, und lässt die anderen weg. Keine der beiden Methoden ändert das ursprüngliche Array.

reduce faltet ein Array zu einem Wert

reduce((sum, n) => sum + n, 0) läuft mit einem laufenden Ergebnis, dem Akkumulator, durch das Array. Beim ersten Aufruf ist sum der Startwert, 0; was der Callback zurückgibt, wird sum für das nächste Element, und die letzte Rückgabe ist das Ergebnis. Geben Sie immer einen Startwert an: 0 für eine Summe, 1 für ein Produkt, "" für zusammengefügten Text. Ohne Startwert beginnt reduce mit dem ersten Element, und ein leeres Array hat keines, also stoppt [].reduce((sum, n) => sum + n) mit TypeError: Reduce of empty array with no initial value. Das passiert leicht nach einem filter, der nichts behält.

Ketten, Tests und die parseInt-Falle

Weil map und filter Arrays zurückgeben, lassen sie sich verketten: steps.filter((n) => n >= 10000).reduce((sum, n) => sum + n, 0). some gibt true zurück, wenn der Callback für mindestens ein Element true ist; every nur, wenn er für alle true ist. forEach ruft den Callback wegen seiner Nebenwirkung auf, etwa einer Ausgabe, und gibt undefined zurück; für ein neues Array nehmen Sie map. Eine Funktion, die Sie per Namen übergeben, erhält alle Argumente: ["1", "2", "3"].map(parseInt) ergibt [ 1, NaN, NaN ], weil parseInt den Index als zweites Argument liest, als Basis. Schreiben Sie map(Number) oder map((s) => parseInt(s, 10)).

Quellen

Zuletzt geprüft am 3. Oktober 2026