JavaScript Object.groupBy() groups values from an iterable into arrays based on a key returned by a callback function. It is useful when you have one collection and need to organize its items by category, status, range, type, or another property before displaying or processing them.
The method became part of ECMAScript 2024. Unlike older patterns that use reduce() to build groups manually, Object.groupBy() expresses the grouping step directly and returns an object whose properties contain the grouped arrays.
How Object.groupBy() Works
Object.groupBy() reads the input iterable in order. For each value, it calls your callback with the value and its zero-based index. The callback returns the key that should identify the group for that value.
The result is a new object. Each property in that object contains an array of the original values that produced the same key.
Object.groupBy() works with iterables, not only arrays. Arrays, sets, and other iterable objects can be grouped.
Object.groupBy() Syntax
// Group iterable values by the key returned from the callback.
const groups = Object.groupBy(items, (value, index) => groupKey);
- items is the iterable whose values you want to group.
- callback runs once for each value and receives the value and its index.
- The callback result is converted to an object property key. String keys are the most common choice.
- The method returns an object containing one array for each group.
Group Objects by a Property
The following example groups orders by their status. The callback returns either pending or shipped, so the result contains two arrays.
Example:
const orders = [
{ item: "Notebook", status: "pending" },
{ item: "Keyboard", status: "shipped" },
{ item: "Mouse", status: "pending" },
{ item: "Monitor", status: "shipped" }
];
// Group orders by their status.
const grouped = Object.groupBy(orders, order => order.status);
console.log("Pending: " + grouped.pending.map(order => order.item).join(", "));
console.log("Shipped: " + grouped.shipped.map(order => order.item).join(", "));
Output:
Pending: Notebook, Mouse
Shipped: Keyboard, Monitor
The original order objects are not copied or transformed. Each grouped array contains references to the original values. If an object is changed later, that same object is visible through the group that contains it.
Create Groups from a Condition
Your callback does not need to return an existing object property. It can calculate a category from each value.
Example:
const scores = [42, 78, 91, 65, 88];
// Create a label from each score.
const levels = Object.groupBy(scores, score => {
return score >= 75 ? "high" : "standard";
});
console.log(levels.high.join(", "));
console.log(levels.standard.join(", "));
Output:
78, 91, 88
42, 65
Group Values from a Set
Because the first argument can be any iterable, you can group values from a Set without converting it to an array first.
Example:
const numbers = new Set([3, 4, 7, 10, 12]);
const parity = Object.groupBy(numbers, number => {
// Return the property name for the group.
return number % 2 === 0 ? "even" : "odd";
});
console.log(parity.even.join(", "));
console.log(parity.odd.join(", "));
Output:
4, 10, 12
3, 7
Understand the Returned Object
The object returned by Object.groupBy() has a null prototype. This design prevents group names from accidentally colliding with inherited Object properties such as constructor or toString.
Because it has no Object prototype, do not call methods such as hasOwnProperty() directly on the result. Use Object.hasOwn() when you need to test whether a group exists.
Example:
const products = ["Pen", "Desk", "Book"];
const byLength = Object.groupBy(products, product => {
return product.length > 3 ? "long" : "short";
});
// Safe property check for a null-prototype result.
console.log(Object.hasOwn(byLength, "long"));
Output:
true
Object.groupBy() and Map.groupBy()
Use Object.groupBy() when your group names naturally fit object property keys, especially strings such as open, paid, admin, or archived.
Use Map.groupBy() when the grouping key should remain an arbitrary value, such as an object. Map keys are not converted to strings, so object identity can be preserved.
| Method | Result | Good choice when |
|---|---|---|
| Object.groupBy() | Object of arrays | Groups have string or symbol property keys |
| Map.groupBy() | Map of arrays | Groups need arbitrary values as keys |
Common Mistakes and Limitations
- Do not expect Object.groupBy() to transform the values. It only decides which group receives each original value.
- Numeric callback results become property keys on the returned object, so string labels are often clearer.
- Do not call inherited Object methods directly on the returned value because its prototype is null.
- If the callback is not a function, or the input cannot be used as an iterable, the operation fails with an error.
- For environments that must support older browsers or runtimes, check compatibility or provide an alternative implementation.
Recommended Practices
- Return short, predictable group keys from the callback.
- Use Object.hasOwn() when checking for a group before reading it.
- Choose Map.groupBy() when object identity or non-string keys matter.
- Keep the callback focused on classification. Perform unrelated transformations before or after grouping.
Conclusion
Object.groupBy() gives JavaScript a direct way to organize iterable values into named arrays. Define a callback that returns the desired group key, then work with the resulting object. It is especially useful for categorizing records by properties or calculated conditions, while Map.groupBy() is a better fit when group keys need full Map semantics.