Map.groupByLoading saved progress…

Map.groupBy

Map.groupBy(items, callbackFn) sorts the values of any iterable into groups and returns a Map whose keys are the values your callback computes and whose values are arrays of the items that produced each key. It is a standard ES2024 method (MDN); here you implement it yourself. Its advantage over the plain-object Object.groupBy is that a Map key can be any value — an object, a number, a boolean, even NaN — so keys are never flattened into strings.

Signature

function mapGroupBy<T, K>(
  items: Iterable<T>,
  callbackFn: (item: T, index: number) => K
): Map<K, T[]>;

items is any iterable — an array, a Set, a generator. callbackFn runs once per item with the item and its 0-based index, and whatever it returns becomes that item's group key.

Examples

// Group numbers by whether they are even or odd.
mapGroupBy([1, 2, 3, 4, 5], (n) => n % 2);
// → Map(2) { 1 => [1, 3, 5], 0 => [2, 4] }
// Keys can be object references — impossible with a plain-object result.
const eng = { team: 'eng' };
const ops = { team: 'ops' };
mapGroupBy(
  [
    { name: 'Ada', dept: eng },
    { name: 'Linus', dept: ops },
    { name: 'Grace', dept: eng },
  ],
  (person) => person.dept
);
// → Map(2) { eng => [Ada, Grace], ops => [Linus] }

Notes

  • Return a Map — not a plain object. Build it with new Map() and return it. Do not call the real Map.groupBy.
  • Any iterableitems may be an array, a Set, or a generator. Walk it with for...of, not a numeric index loop, so all of them work.
  • The index is 0-based — the callback's second argument counts 0, 1, 2, … across the iteration, like Array.prototype.map.
  • Keys keep their identity — two items that produce the same object reference (or the same NaN) share a bucket; different references stay separate. That is the SameValueZero equality a Map uses.
  • First-seen order — keys appear in the order they were first produced, and items within a bucket stay in iteration order.
Loading editor…