Skip to main content

Command Palette

Search for a command to run...

Streamline Your Data Wrangling: Introducing Object.groupBy() and Map.groupBy()

Updated
4 min read
Streamline Your Data Wrangling: Introducing Object.groupBy() and Map.groupBy()

As JavaScript developers, we often find ourselves needing to group elements within an array based on a specific criterion. Before ECMAScript 2024, this typically involved a manual reduce operation or a loop with some conditional logic, which could sometimes be a bit verbose.

Enter Object.groupBy() and Map.groupBy() – two new static methods that provide a more declarative and concise way to achieve this common task. [8, 11] They take an iterable (like an array) and a callback function. The callback function determines the key under which each element should be grouped.

The Power of Grouping, Simplified

Imagine you have an array of product objects, and you want to group them by their category.

Before Object.groupBy():

const products = [
  { name: "Laptop", category: "Electronics", price: 1200 },
  { name: "Shirt", category: "Apparel", price: 50 },
  { name: "Keyboard", category: "Electronics", price: 75 },
  { name: "Jeans", category: "Apparel", price: 80 },
  { name: "Mouse", category: "Electronics", price: 25 },
];

// Using reduce (a common pre-ES2024 approach)
const productsByCategoryOld = products.reduce((acc, product) => {
  const key = product.category;
  if (!acc[key]) {
    acc[key] = [];
  }
  acc[key].push(product);
  return acc;
}, {});

console.log(productsByCategoryOld);
/*
Output:
{
  Electronics: [
    { name: 'Laptop', category: 'Electronics', price: 1200 },
    { name: 'Keyboard', category: 'Electronics', price: 75 },
    { name: 'Mouse', category: 'Electronics', price: 25 }
  ],
  Apparel: [
    { name: 'Shirt', category: 'Apparel', price: 50 },
    { name: 'Jeans', category: 'Apparel', price: 80 }
  ]
}
*/

This works, but it requires a bit of boilerplate to initialize the arrays for each group.

With Object.groupBy():

Now, let's see how Object.groupBy() simplifies this:

const products = [
  { name: "Laptop", category: "Electronics", price: 1200 },
  { name: "Shirt", category: "Apparel", price: 50 },
  { name: "Keyboard", category: "Electronics", price: 75 },
  { name: "Jeans", category: "Apparel", price: 80 },
  { name: "Mouse", category: "Electronics", price: 25 },
];

const productsByCategoryNew = Object.groupBy(products, (product) => product.category);

console.log(productsByCategoryNew);
/*
Output (note: the prototype of the resulting object is null):
{
  Electronics: [
    { name: 'Laptop', category: 'Electronics', price: 1200 },
    { name: 'Keyboard', category: 'Electronics', price: 75 },
    { name: 'Mouse', category: 'Electronics', price: 25 }
  ],
  Apparel: [
    { name: 'Shirt', category: 'Apparel', price: 50 },
    { name: 'Jeans', category: 'Apparel', price: 80 }
  ]
}
*/

Much cleaner, right? The Object.groupBy() method returns a null-prototype object where keys are the group identifiers (in this case, "Electronics" and "Apparel") and values are arrays of the elements belonging to that group. [11]

When to Use Map.groupBy()?

The Map.groupBy() method is very similar but returns a Map instance instead of a plain object. [11] This can be advantageous when:

  • You need to use non-string keys: Map keys can be any value (objects, functions, etc.), whereas plain object keys are always coerced to strings (or Symbols).

  • You need to preserve insertion order (for keys): Maps remember the original insertion order of keys.

  • You need built-in size property and other Map methods: Map objects have a handy .size property and methods like .has(), .get(), .set(), .delete(), etc.

Here's the same example using Map.groupBy():

const products = [
  { name: "Laptop", category: "Electronics", price: 1200 },
  { name: "Shirt", category: "Apparel", price: 50 },
  { name: "Keyboard", category: "Electronics", price: 75 },
  { name: "Jeans", category: "Apparel", price: 80 },
  { name: "Mouse", category: "Electronics", price: 25 },
];

const productsByCategoryMap = Map.groupBy(products, (product) => product.category);

console.log(productsByCategoryMap);
/*
Output:
Map(2) {
  'Electronics' => [
    { name: 'Laptop', category: 'Electronics', price: 1200 },
    { name: 'Keyboard', category: 'Electronics', price: 75 },
    { name: 'Mouse', category: 'Electronics', price: 25 }
  ],
  'Apparel' => [
    { name: 'Shirt', category: 'Apparel', price: 50 },
    { name: 'Jeans', category: 'Apparel', price: 80 }
  ]
}
*/

// You can then easily iterate or access elements:
console.log(productsByCategoryMap.get("Electronics"));

Why is this a "Very Useful Tweak"?

  1. Readability: The intent of the code becomes much clearer. Object.groupBy(items, callback) immediately tells you what's happening.

  2. Conciseness: It significantly reduces the amount of boilerplate code needed for a common operation.

  3. Reduced Errors: Less manual logic means fewer opportunities for small mistakes in setting up the accumulator or managing arrays.

  4. Standardization: It provides a standard, built-in way to perform grouping, leading to more consistent codebases. [8]

Browser Support and Transpilation

As Object.groupBy() and Map.groupBy() are part of ECMAScript 2024, modern browsers are quickly adopting them. [1, 8] For older environments, you'll likely need to rely on transpilers like Babel along with polyfills to use this feature. [5] However, as you build projects for 2025 and beyond, you can expect to use these natively more and more.

Conclusion

While seemingly small, Object.groupBy() and Map.groupBy() are excellent examples of how JavaScript continues to evolve to make developers' lives easier. [1, 8] They address a frequent need with an elegant and efficient solution, allowing you to write cleaner, more maintainable code. So, next time you need to group data, remember these handy additions!

11 views

More from this blog

Nureddin Badawi

7 posts

I build scalable, high-performance applications across frontend, backend, and cloud infrastructure. and I excel in modern React-based frontend ecosystems.