JavaScript

Array#group and Array#groupToMap

3 min read

The array grouping proposal for ECMAScript defines two additional array methods: group and groupToMap. These methods are inspired by the groupBy Lodash method.

group groups items by key in an object. The return value of your function is used as the key. The key’s value is an array of all values for which the callback returned that key.

const words = "fragment program functional say anxiety east fresh pocket liver future".split(" ");
words.group((word) => word[0]);

[Object: null prototype] indicates that the return value of group was created with Object.create(null). This is a regular object with, as it says, a null prototype, rather than Object.prototype. This means you cannot use methods like .hasOwnProperty on it. Use Object.hasOwn instead.

Like utility methods such as map, you receive three arguments in your callback: (value, index, array)

const numbers = [10, 40, 20, 30, 50, 60];
numbers.group((_, index) => (index % 2 === 0 ? "evenIndex" : "oddIndex"));

By virtue of receiving the current value’s index, it is also possible to check the values of surrounding elements to determine how to group a value.

Object values are referenced instead of cloned. If you mutate them using the original array, this is also reflected in the group object:

const users = [
  { cohort: "A", id: 1 },
  { cohort: "B", id: 2 },
  { cohort: "A", id: 3 },
];
const groupedByCohort = users.group((user) => user.cohort);
console.log(JSON.stringify(groupedByCohort));
users[0].role = "moderator";
console.log(JSON.stringify(groupedByCohort));

It is permitted to mutate the original array inside .group, but it only visits the elements that existed by the time you called it:

const flags = [true, false, true];
const groupedByValue = flags.group((value, _, array) => {
  array.push(value);
  return value;
});
console.log(groupedByValue);
console.log(flags);

groupToMap creates a Map instead (which can use any type of key, not just strings):

const words = "fragment program functional say anxiety east fresh pocket liver future".split(" ");
words.groupToMap((word) => word[0]);

As of writing, only Firefox ships these methods, and only in its nightly edition. core-js does provide a polyfill that you can easily include in your bundle like so:

import "core-js/proposals/array-grouping-stage-3-2";

Afterwards, group and groupToMap will be available on all arrays.