Array.prototype.filter() erzeugt ein neues Array mit allen Elementen, für die der Predicate-Callback einen truthy-Wert liefert. Wie map ist filter immutable — das Original bleibt unangetastet. Die Methode ist eines der zentralen Bausteine in Filter-Map-Reduce-Pipelines: erst irrelevante Werte entfernen, dann transformieren, dann aggregieren. Der Callback bekommt (element, index, array); nur das erste Argument wird in den meisten Fällen genutzt. filter läuft über alle Elemente — es gibt kein Early-Exit.

Signatur & Grundform

JavaScript signatur.js
arr.filter(predicate: (el: T, i: number, arr: T[]) => boolean, thisArg?): T[]
JavaScript grundform.js
const zahlen = [1, 2, 3, 4, 5, 6];

const geraden = zahlen.filter(n => n % 2 === 0);
console.log(geraden);        // [2, 4, 6]
console.log(zahlen);         // [1, 2, 3, 4, 5, 6] — unverändert
Output
[ 2, 4, 6 ]
[ 1, 2, 3, 4, 5, 6 ]

Truthy / Falsy — der Predicate-Test

Der Callback muss keinen Boolean zurückgeben — jede truthy/falsy-Wert reicht. Klassischer Trick: filter(Boolean) entfernt alle falsy Werte (null, undefined, 0, '', false, NaN).

JavaScript truthy.js
const mix = [1, 0, 'hi', '', null, 5, undefined, NaN, 'x'];

// Truthy filtern
const truthy = mix.filter(Boolean);
console.log(truthy);         // [1, 'hi', 5, 'x']

// Nur Numbers
const nums = mix.filter(x => typeof x === 'number' && !isNaN(x));
console.log(nums);
Output
[ 1, 'hi', 5, 'x' ]
[ 1, 0, 5 ]

filter(Boolean) ist eines der nützlichsten Eine-Zeilen-Patterns in modernem JavaScript.

Object-Filter

JavaScript object-filter.js
const users = [
    { name: 'Anna',  alter: 30, aktiv: true },
    { name: 'Bob',   alter: 17, aktiv: true },
    { name: 'Chris', alter: 25, aktiv: false },
    { name: 'Dora',  alter: 40, aktiv: true },
];

// Erwachsene & aktive
const erlaubt = users.filter(u => u.alter >= 18 && u.aktiv);
console.log(erlaubt.map(u => u.name));
Output
[ 'Anna', 'Dora' ]

Filter-Map-Reduce-Pipeline

filter + map + reduce ist die ikonische funktionale Pipeline.

JavaScript pipeline.js
const orders = [
    { id: 1, betrag: 50,  cancelled: false },
    { id: 2, betrag: 100, cancelled: true },
    { id: 3, betrag: 75,  cancelled: false },
    { id: 4, betrag: 200, cancelled: false },
];

const totalAktiv = orders
    .filter(o => !o.cancelled)
    .map(o => o.betrag)
    .reduce((acc, b) => acc + b, 0);

console.log(totalAktiv);     // 50 + 75 + 200 = 325
Output
325

Negieren — Komplement bilden

filter(p) und filter(x => !p(x)) ergeben zusammen das Original-Array.

JavaScript negieren.js
const items = [1, 2, 3, 4, 5];

const geraden = items.filter(n => n % 2 === 0);
const ungeraden = items.filter(n => n % 2 !== 0);

console.log(geraden);        // [2, 4]
console.log(ungeraden);      // [1, 3, 5]

// Partition in einer Zeile (helper)
function partition(arr, pred) {
    return [arr.filter(pred), arr.filter(x => !pred(x))];
}
const [erw, kind] = partition([20, 5, 30, 12], a => a >= 18);
console.log(erw, kind);
Output
[ 2, 4 ]
[ 1, 3, 5 ]
[ 20, 30 ] [ 5, 12 ]

Die partition-Hilfsfunktion läuft zweimal über das Array — bei großen Daten lohnt eine einmalige reduce-Lösung, die beide Buckets in einem Pass baut.

filter vs. find / some / every

  • filter: alle passenden Elemente, immer komplettes Durchlaufen.
  • find: erstes passendes Element, mit Early Exit.
  • some: gibt true, sobald ein Element passt — Early Exit.
  • every: gibt false, sobald ein Element nicht passt — Early Exit.
JavaScript filter-vs-find.js
const arr = [1, 2, 3, 4, 5];

// Alle geraden
console.log(arr.filter(n => n % 2 === 0));   // [2, 4]

// Erstes gerade
console.log(arr.find(n => n % 2 === 0));     // 2

// Gibt es ein gerades?
console.log(arr.some(n => n % 2 === 0));     // true

// Sind ALLE gerade?
console.log(arr.every(n => n % 2 === 0));    // false
Output
[ 2, 4 ]
2
true
false

Wer nur eines sucht: find statt filter()[0]. Wer prüfen will, ob mindestens/alle passen: some/every.

Mit Index — Position-basiertes Filtern

JavaScript index-filter.js
const arr = ['a', 'b', 'c', 'd', 'e', 'f'];

// Jedes zweite
const jedesZweite = arr.filter((_, i) => i % 2 === 0);
console.log(jedesZweite);    // ['a', 'c', 'e']

// Erste drei
const ersten = arr.filter((_, i) => i < 3);
console.log(ersten);         // ['a', 'b', 'c']

// Letzte zwei — aber slice ist hier idiomatischer
console.log(arr.slice(-2));
Output
[ 'a', 'c', 'e' ]
[ 'a', 'b', 'c' ]
[ 'e', 'f' ]

Bei reinen Index-Filtern (erste/letzte n Elemente) ist slice oft besser. filter glänzt bei Predicate-basierten Tests.

Sparse Arrays — Löcher werden übersprungen

Wie map ruft filter den Predicate nicht für Löcher auf. Das Ergebnis ist immer dense.

JavaScript sparse.js
const sparse = [1, , 3, , 5];
const truthy = sparse.filter(x => x);
console.log(truthy);         // [1, 3, 5] — dense
console.log(truthy.length);  // 3
Output
[ 1, 3, 5 ]
3

Interessantes

filter(Boolean) ist das Standard-Pattern für falsy-Cleanup

arr.filter(Boolean) entfernt null, undefined, 0, '', false, NaN in einer Zeile. Eines der nützlichsten Eine-Zeilen-Patterns in JavaScript.

filter ist immutable — Original bleibt unverändert

Wie map, concat, slice erzeugt filter ein neues Array. Standard für State-Updates in Redux/React.

Kein Early Exit — durchläuft IMMER das ganze Array

Anders als find, some, every kann filter nicht vorzeitig abbrechen. Bei sehr großen Arrays, in denen man nur die ersten n Treffer braucht, ist eine for-Schleife mit break schneller.

Predicate kann jeden truthy-Wert zurückgeben, nicht nur Boolean

arr.filter(x => x.value) — wenn x.value truthy ist, wird das Element behalten. Praktisch beim Filtern nach Property-Existenz.

filter + map kann durch reduce ersetzt werden — eine Iteration

arr.filter(p).map(f) macht zwei Iterationen. arr.reduce((acc, x) => p(x) ? [...acc, f(x)] : acc, []) macht eine. Bei normalem Code unwichtig; bei großen Arrays messbar. Modern: Iterator Helpers (ES2025).

Async Predicate funktioniert NICHT direkt

arr.filter(async x => await check(x)) liefert alle Elemente — async-Funktionen geben immer ein Promise zurück, und Promises sind truthy. Lösung: await Promise.all(arr.map(check)) + sync filter.

ESLint array-callback-return warnt bei filter ohne return

arr.filter(x => { console.log(x); }) liefert immer [] — der Callback gibt undefined zurück, alles wird gefiltert. Linter erkennen das als Bug.

Unique mit Set ist schneller als Filter mit indexOf

Klassisches Dedup: arr.filter((x, i, a) => a.indexOf(x) === i) ist O(n²). [...new Set(arr)] ist O(n). Bei Primitives immer Set bevorzugen.

Weiterführende Ressourcen

Externe Quellen

/ Weiter

Zurück zu Arrays

Zur Übersicht