Signatur
Beschreibung
Map.groupBy() ist eine statische Methode. Sie läuft einmal über ein beliebiges Iterable, zum Beispiel ein Array, ein Set, einen Generator oder eine NodeList. Für jedes Element ruft sie die Callback-Funktion auf. Der Rückgabewert des Callbacks ist der Gruppenschlüssel. Das Element wird dann an das Array dieses Schlüssels in der Ergebnis-Map angehängt.
Der Unterschied zu Object.groupBy(): Die Schlüssel werden nicht in Strings umgewandelt. Sie können also beliebige Werte sein, auch Objekte, Symbole oder NaN. Verglichen wird wie bei Map üblich mit dem Algorithmus SameValueZero. Objekt-Schlüssel gelten also nur dann als gleich, wenn es dieselbe Referenz ist.
Setzen Sie Map.groupBy() ein, wenn Sie nach Objekten gruppieren wollen (etwa nach einer Kategorie-Instanz) oder wenn Sie die Ergebnis-Map später weiterbearbeiten wollen, etwa mit set, delete oder size. Die Gruppen erscheinen in der Reihenfolge, in der ihr Schlüssel zum ersten Mal auftaucht. Innerhalb jeder Gruppe bleibt die ursprüngliche Reihenfolge der Elemente erhalten.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $items Pflicht | Iterable<T> | Das Iterable, dessen Elemente gruppiert werden, z. B. Array, Set, Map oder ein Generator. |
|
| $callbackFn Pflicht | (element: T, index: number) => K | Wird für jedes Element aufgerufen und bekommt das element und seinen fortlaufenden index. Der Rückgabewert ist der Gruppenschlüssel und darf jeden beliebigen Typ haben. |
Rückgabewert
Map. Jeder Schlüssel ist ein vom Callback gelieferter Wert, der Wert dazu ist ein Array mit allen Elementen dieser Gruppe.Beispiele
Lagerbestand nach Status gruppieren
const inventar = [
{ name: 'Spargel', typ: 'Gemüse', menge: 9 },
{ name: 'Bananen', typ: 'Obst', menge: 5 },
{ name: 'Ziege', typ: 'Fleisch', menge: 23 },
{ name: 'Kirschen', typ: 'Obst', menge: 12 },
{ name: 'Fisch', typ: 'Fleisch', menge: 22 }
];
const ergebnis = Map.groupBy(inventar, ({ menge }) =>
menge < 10 ? 'nachbestellen' : 'ausreichend'
);
console.log(ergebnis.get('nachbestellen').map(p => p.name));
console.log(ergebnis.size);
Objekte als Gruppenschlüssel verwenden
const knapp = { label: 'knapp' };
const ok = { label: 'ok' };
const produkte = [
{ name: 'Mehl', menge: 3 },
{ name: 'Zucker', menge: 40 },
{ name: 'Salz', menge: 1 }
];
const gruppen = Map.groupBy(produkte, p => (p.menge < 5 ? knapp : ok));
// Zugriff nur über dieselbe Objekt-Referenz
console.log(gruppen.get(knapp).map(p => p.name));
console.log(gruppen.get({ label: 'knapp' }));
Generator gruppieren und Index nutzen
function* zahlen(n) {
for (let i = 1; i <= n; i++) yield i;
}
// Gerade/ungerade als boolesche Schlüssel
const paritaet = Map.groupBy(zahlen(6), x => x % 2 === 0);
console.log([...paritaet]);
// In Dreierblöcke aufteilen über den Index
const bloecke = Map.groupBy(['a', 'b', 'c', 'd', 'e'], (_, i) => Math.floor(i / 3));
console.log([...bloecke.values()]);
Fallback für ältere Umgebungen
const groupBy = (items, fn) => {
if (typeof Map.groupBy === 'function') return Map.groupBy(items, fn);
const map = new Map();
let i = 0;
for (const item of items) {
const key = fn(item, i++);
if (!map.has(key)) map.set(key, []);
map.get(key).push(item);
}
return map;
};
console.log(groupBy(['Apfel', 'Birne', 'Avocado'], w => w[0]));
// Wichtig · Fallstricke
- Statische Methode: Der Aufruf lautet
Map.groupBy(arr, fn), nichtarr.groupBy(). Eine Array-MethodeArray.prototype.group()war zwar vorgeschlagen, wurde aber wegen Kompatibilitätsproblemen mit bestehendem Code verworfen. - Objekt-Schlüssel werden per Referenz verglichen: Zwei Objekte mit gleichem Inhalt ergeben trotzdem getrennte Gruppen. Wenn Sie nach Inhalt gruppieren wollen, geben Sie im Callback einen primitiven Wert zurück, etwa eine ID oder einen String.
- Flache Kopie: Die Arrays der Gruppen enthalten dieselben Objekt-Referenzen wie das Original. Wenn Sie ein Element ändern, ändert sich das Original mit.
- Keine leeren Gruppen: Ein Schlüssel kommt nur dann in der Map vor, wenn mindestens ein Element dazugehört. Prüfen Sie also mit
map.get(key) ?? []. - Kompatibilität: Verfügbar ab ES2024: Chrome/Edge 117, Firefox 119, Safari 17.4, Node.js 21. Für ältere Umgebungen brauchen Sie ein Polyfill (z. B.
core-js) oder einen eigenen Fallback. In TypeScript musslibaufES2024oderESNextstehen. - Gibt
callbackFnkeinen Wert zurück, landen die Elemente unter dem Schlüsselundefined. Das ist erlaubt, aber meist ein Programmierfehler.