Object.groupBy – Listen gruppieren, ohne reduce zu schreiben
„Alle Bestellungen nach Status" war jahrelang ein reduce mit Startwert, Prüfung auf das Fach und push. Seit Object.groupBy ist es eine Zeile – und die liest man auch nach einem halben Jahr noch.
Gruppieren ist eine der häufigsten Aufgaben überhaupt: Bestellungen nach Status, Termine nach Tag, Produkte nach Kategorie. Der klassische Weg sah so aus:
const nachStatus = bestellungen.reduce((acc, b) => {
(acc[b.status] ||= []).push(b);
return acc;
}, {});Funktioniert – aber drei Zeilen Mechanik für einen Gedanken.
Eine Zeile
const nachStatus = Object.groupBy(bestellungen, b => b.status);
// {
// offen: [ {…}, {…} ],
// bezahlt: [ {…} ],
// storniert:[ {…} ]
// }Die Rückgabefunktion liefert den Gruppenschlüssel. Das Ergebnis ist ein Objekt ohne Prototyp (null-Prototyp), damit ein Datensatz mit dem Status constructor oder __proto__ nichts kaputt macht.
Auch für gerechnete Schlüssel
const nachMonat = Object.groupBy(
termine,
t => new Date(t.datum).toLocaleDateString('de-DE', { month: 'long', year: 'numeric' })
);
const nachPreisklasse = Object.groupBy(produkte, p =>
p.preis < 20 ? 'guenstig' : p.preis < 100 ? 'mittel' : 'teuer'
);Der zweite Parameter der Funktion ist übrigens der Index – praktisch für „jede zweite Zeile":
const zebra = Object.groupBy(zeilen, (_, i) => (i % 2 ? 'ungerade' : 'gerade'));Map.groupBy, wenn der Schlüssel kein String ist
Object.groupBy wandelt jeden Schlüssel in einen String. Willst du nach einem Objekt, einer Zahl oder einem Datum gruppieren und das auch zurückbekommen, nimm die Map-Variante:
const nachKunde = Map.groupBy(bestellungen, b => b.kunde); // Schlüssel bleibt das Kundenobjekt
for (const [kunde, liste] of nachKunde) {
console.log(kunde.name, liste.length);
}Fallstrick
Zwei Dinge. Erstens: Die Reihenfolge der Gruppen folgt der Reihenfolge des ersten Auftretens – bei numerischen Schlüsseln sortiert ein Objekt sie allerdings aufsteigend, weil JavaScript Integer-Schlüssel so behandelt. Wenn die Reihenfolge zählt, nimm Map.groupBy. Zweitens: Beide Methoden sind verhältnismäßig neu (ES2024). In aktuellen Browsern und in Node ab Version 21 sind sie da; für ältere Ziele hilft ein kleiner Ersatz mit reduce – oder du prüfst vorher typeof Object.groupBy === 'function'.
Sauberes, gut lesbares Frontend gehört zu jedem Projekt, das ich baue. Melde dich über bymw.de.
Quellen
Du brauchst mehr als ein Snippet?
Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.
Projekt anfragen →Verwandte Snippets
toSorted, toReversed und with: Arrays sortieren, ohne das Original zu zerstören
array.sort() sortiert nicht eine Kopie, sondern das Array selbst – und genau daran ist schon mancher Zustand im Frontend stillschweigend kaputtgegangen. Seit ES2023 gibt es zu jeder dieser Methoden eine Variante, die eine Kopie zurückgibt.
Web Worker – rechnen, ohne die Oberfläche einzufrieren
JavaScript hat im Browser genau einen Faden für alles: Klicks, Animationen, Layout – und deine Rechenschleife. Dauert die zwei Sekunden, ist die Seite zwei Sekunden lang tot. Ein Worker nimmt die Arbeit auf einen eigenen Faden.
Formulare ohne Neuladen abschicken – FormData und fetch
Ein Formular per JavaScript abzuschicken heißt nicht, jedes Feld einzeln auszulesen. FormData nimmt das ganze Formular, fetch schickt es weg – inklusive Dateien, und mit einer Fehlermeldung, die der Besucher versteht.