Post cover

Array Grouping in JavaScript: array.groupBy()

Updated January 28, 2023

Many developers appreciate Ruby programming language because of the rich standard utility libraries. For example, the array in Ruby has a huge number of methods.

JavaScript also enriches its standard library on strings and arrays step by step. For example, in a previous post, I described the new array.at() method.

Today's hero is the new array group proposal (currently at stage 3) that introduces new methods array.groupBy() and array.groupByToMap(). Their polyfills are available in core-js library.

Let's see how you may benefit from the grouping methods.

Before I go on, let me recommend something to you.

If you want to significantly improve your JavaScript knowledge, take the amazingly useful course "Modern JavaScript From The Beginning 2.0" by Brad Traversy. Use the coupon code "DMITRI" and get 20% discount!

1. array.groupBy()

You have a list of products, where each product is an object having 2 properties: name and category.

javascript
const products = [
{ name: 'apples', category: 'fruits' },
{ name: 'oranges', category: 'fruits' },
{ name: 'potatoes', category: 'vegetables' }
];

In the example above products is an array of product objects.

Now your task is to group the products by category. The result would look like this:

javascript
const groupByCategory = {
'fruits': [
{ name: 'apples', category: 'fruits' },
{ name: 'oranges', category: 'fruits' },
],
'vegetables': [
{ name: 'potatoes', category: 'vegetables' }
]
};

How would you get an array like groupByCategory from products array in JavaScript?

The usual way is by invoking the array.reduce() method with a callback function implementing the grouping logic:

javascript
const groupByCategory = products.reduce((group, product) => {
const { category } = product;
group[category] = group[category] ?? [];
group[category].push(product);
return group;
}, {});
console.log(groupByCategory);
// {
// 'fruits': [
// { name: 'apples', category: 'fruits' },
// { name: 'oranges', category: 'fruits' },
// ],
// 'vegetables': [
// { name: 'potatoes', category: 'vegetables' }
// ]
// }

Try the demo.

products.reduce((acc, product) => { ... }) reduces the products array to an object of products grouped by category.

While I do consider array.reduce() method useful and powerful, sometimes its readability is not the best.

Because grouping data is an often occurring task (recall GROUP BY from SQL?) the array group proposal introduces two useful methods: array.groupBy() and array.groupByToMap().

Here's how you would use array.groupBy() to create the same grouping by category:

javascript
const groupByCategory = products.groupBy(product => {
return product.category;
});
console.log(groupByCategory);
// {
// 'fruits': [
// { name: 'apples', category: 'fruits' },
// { name: 'oranges', category: 'fruits' },
// ],
// 'vegetables': [
// { name: 'potatoes', category: 'vegetables' }
// ]
// }

Try the demo.

products.groupBy(product => {...}) returns an object where properties are category names and values are arrays of category products.

Grouping using products.groupBy() requires less code and is easier to understand than using product.reduce().

array.groupBy(callback) accepts a callback function that's invoked with 3 arguments: the current array item, the index, and the array itself. The callback should return a string: the group name where you'd like to add the item.

javascript
const groupedObject = array.groupBy((item, index, array) => {
// ...
return groupNameAsString;
});

2. array.groupByToMap()

Sometimes you may want to use a Map instead of a plain object. The benefit of Map is that it accepts any data type as a key, but the plain object is limited to strings and symbols only.

So, if you'd like to group data into a Map, you can use the method array.groupByToMap().

array.groupByToMap(callback) works the same way as array.groupBy(callback), only that it groups items into a Map instead of a plain JavaScript object.

For example, grouping the products array into a map by category name is performed as follows:

javascript
const groupByCategory = products.groupByToMap(product => {
return product.category;
});
console.log(groupByCategory);
// Map([
// ['fruits', [
// { name: 'apples', category: 'fruits' },
// { name: 'oranges', category: 'fruits' },
// ]],
// ['vegetables', [
// { name: 'potatoes', category: 'vegetables' }
// ]
// ])

Try the demo.

3. Conclusion

If you want to easily group the items of an array (similarly to GROUP BY in SQL), then welcome the new methods array.groupBy() and array.groupByToMap().

Both functions accept a callback that should return the key of the group where the current items must be inserted.

array.groupBy() groups the items into a plain JavaScript object, while array.groupByToMap() groups them into a Map instance.

If you'd like to use these functions right away, then use the polyfill provided by core-js library.

Like the post? Please share!

Quality posts into your inbox

I regularly publish posts containing:

  • Important JavaScript concepts explained in simple words
  • Overview of new JavaScript features
  • How to use TypeScript and typing
  • Software design and good coding practices

Subscribe to my newsletter to get them right into your inbox.

Join 7094 other subscribers.
Dmitri Pavlutin

About Dmitri Pavlutin

Tech writer and coach. My daily routine consists of (but not limited to) drinking coffee, coding, writing, coaching, overcoming boredom 😉.

Quality posts into your inbox

I regularly publish posts containing:

  • Important JavaScript concepts explained in simple words
  • Overview of new JavaScript features
  • How to use TypeScript and typing
  • Software design and good coding practices

Subscribe to my newsletter to get them right into your inbox.

Join 7094 other subscribers.
Dmitri Pavlutin

About Dmitri Pavlutin

Tech writer and coach. My daily routine consists of (but not limited to) drinking coffee, coding, writing, coaching, overcoming boredom 😉.