Start · Sprachen · JavaScript · Referenz · Map.groupBy()

Map.groupBy()

Methode

Gruppiert die Elemente eines Iterables anhand der Schlüssel, die eine Callback-Funktion liefert, und gibt eine <code>Map</code> mit Arrays pro Gruppe zurück.

seit JavaScript ES2024 (Baseline 2024: Chrome 117, Firefox 119, Sa Kategorie: method-property

Signatur

Map.groupBy(items, callbackFn)

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

Typ
Map<K, T[]>
Beschreibung
Eine neue 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);
[ 'Spargel', 'Bananen' ] 2

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' }));
[ 'Mehl', 'Salz' ] undefined

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()]);
[ [ false, [ 1, 3, 5 ] ], [ true, [ 2, 4, 6 ] ] ] [ [ 'a', 'b', 'c' ], [ 'd', 'e' ] ]

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]));
Map(2) { 'A' => [ 'Apfel', 'Avocado' ], 'B' => [ 'Birne' ] }

// Wichtig · Fallstricke

  • Statische Methode: Der Aufruf lautet Map.groupBy(arr, fn), nicht arr.groupBy(). Eine Array-Methode Array.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 muss lib auf ES2024 oder ESNext stehen.
  • Gibt callbackFn keinen Wert zurück, landen die Elemente unter dem Schlüssel undefined. Das ist erlaubt, aber meist ein Programmierfehler.