How to Use Object.groupBy and Map.groupBy in JavaScript
Modern JavaScript introduces native collection grouping with
Object.groupBy() and Map.groupBy(),
eliminating the need for external utility libraries like Lodash or
complex Array.prototype.reduce() implementations. This
article covers how these two static methods work, their syntax,
practical code examples, and the key differences between them to help
you choose the right approach for your data.
The Problem with Traditional Grouping
Before these methods were standardized in ECMAScript 2024, grouping
elements in an array required verbose boilerplate code using
reduce():
const inventory = [
{ name: "Asparagus", type: "vegetables", quantity: 5 },
{ name: "Bananas", type: "fruit", quantity: 0 },
{ name: "Cherries", type: "fruit", quantity: 12 },
];
// The old way
const grouped = inventory.reduce((acc, item) => {
const key = item.type;
if (!acc[key]) {
acc[key] = [];
}
acc[key].push(item);
return acc;
}, {});Native grouping replaces this boilerplate with a single, highly readable function call.
Using Object.groupBy()
Object.groupBy() accepts an iterable (such as an array)
and a callback function that determines the group key for each element.
It returns a null-prototype object where each key
corresponds to a group containing an array of matched items.
Syntax
Object.groupBy(items, callbackFn)Example: Grouping by a Property
const inventory = [
{ name: "Asparagus", type: "vegetables", quantity: 5 },
{ name: "Bananas", type: "fruit", quantity: 0 },
{ name: "Cherries", type: "fruit", quantity: 12 },
];
const result = Object.groupBy(inventory, ({ type }) => type);
console.log(result);
/* Output:
{
vegetables: [
{ name: "Asparagus", type: "vegetables", quantity: 5 }
],
fruit: [
{ name: "Bananas", type: "fruit", quantity: 0 },
{ name: "Cherries", type: "fruit", quantity: 12 }
]
}
*/Example: Grouping by Conditional Logic
Keys do not have to be existing properties; you can compute them dynamically:
const stockStatus = Object.groupBy(inventory, ({ quantity }) => {
return quantity > 0 ? "inStock" : "outOfStock";
});
console.log(stockStatus);
/* Output:
{
inStock: [
{ name: "Asparagus", ... },
{ name: "Cherries", ... }
],
outOfStock: [
{ name: "Bananas", ... }
]
}
*/Using Map.groupBy()
Map.groupBy() functions identically to
Object.groupBy(), but returns a standard JavaScript
Map instead of a plain object. This is crucial when your
grouping keys need to be complex data types, such as objects, functions,
or primitives other than strings and symbols.
Syntax
Map.groupBy(items, callbackFn)Example: Grouping with Complex Object Keys
In Object.groupBy(), object keys are automatically
coerced into strings ("[object Object]").
Map.groupBy() preserves reference equality for keys:
const restockInfo = { urgency: "high" };
const normalInfo = { urgency: "low" };
const inventory = [
{ name: "Asparagus", quantity: 5 },
{ name: "Bananas", quantity: 0 },
{ name: "Cherries", quantity: 12 },
];
const groupedByPriority = Map.groupBy(inventory, ({ quantity }) => {
return quantity === 0 ? restockInfo : normalInfo;
});
console.log(groupedByPriority.get(restockInfo));
// Output: [{ name: "Bananas", quantity: 0 }]Key Differences:
Object.groupBy vs Map.groupBy
| Feature | Object.groupBy() |
Map.groupBy() |
|---|---|---|
| Return Type | Plain object with a null
prototype |
Standard Map instance |
| Key Coercion | Keys are converted to strings or symbols | Preserves original key types (objects, numbers, etc.) |
| Access Method | Property access (result.key
or result['key']) |
Map methods (result.get(key),
result.has(key)) |
| Serialization | Directly serializable to JSON via
JSON.stringify() |
Requires conversion before JSON serialization |
Runtime Support
Both Object.groupBy and Map.groupBy are
standard JavaScript features supported across all modern web browsers
(Chrome, Edge, Firefox, Safari) and server-side runtimes including
Node.js (version 21 and above) and Deno.