5 Ways To Group an Array of Objects
Introduction
When working with data in JavaScript, it's often necessary to group an array of objects based on certain criteria. This can be useful for organizing data for display purposes or for performing calculations on subsets of the data.
In this How-To Guide, we'll explore the various methods available for grouping arrays of objects in JavaScript.
Here are 5 methods we can use:
reduce()
methodmap()
methodforEach()
methodfor
orfor...of
loopArray.prototype.group()
orArray.prototype.groupToMap()
Results we are looking for
There are 2 types of result based on your requirement
Group an array of objects into object (this is the common result we are looking for)
{
female: [
{ name: 'Alice', age: 25, gender: 'female' },
{ name: 'Eve', age: 45, gender: 'female' }
],
male: [
{ name: 'Bob', age: 30, gender: 'male' },
{ name: 'Charlie', age: 35, gender: 'male' },
{ name: 'Dave', age: 40, gender: 'male' }
]
}
Group into Array of Arrays
[
[
{ category: "fruit", name: "apple" },
{ category: "fruit", name: "banana" },
{ category: "fruit", name: "orange" },
],
[
{ category: "vegetable", name: "carrot" },
{ category: "vegetable", name: "celery" },
],
];
Method 1: Group an Array of Objects With reduce() Method
The reduce() method can be used to group an array of objects into an object with properties corresponding to the grouped values.
Here are the step-by-step instructions for using the reduce() method to group an array of objects:
Define the array of objects
Here we have an array of person with name
, age
and gender
properties. We will group this data by gender
.
const data = [
{ name: "Alice", age: 25, gender: "female" },
{ name: "Bob", age: 30, gender: "male" },
{ name: "Charlie", age: 35, gender: "male" },
{ name: "Dave", age: 40, gender: "male" },
{ name: "Eve", age: 45, gender: "female" },
];
Define the key to group the objects by
We need to define the key to group an array of objects. Here, your key is gender
.
const key = "gender";
Group the objects with reduce()
Now it's time to group the data. I will not explain how reduce()
work to keep this guide simple. If you are looking for a deep explaination for it, this guide is for you, it covers the reduce()
method.
// reduce() method return a single value, the accumulated value return by the callback function
// The first arguments is the acumulator and the second one is the currentValue of the array
const groupedData = data.reduce((groups, item) => {
const val = item[key]; // key used to group the data
groups[val] = groups[val] || [];
groups[val].push(item); // Push the current item into the corresponding group
return groups; // this return value will be the next accumulator (here groups)
}, {});
Or like this
May be hard to read if you or one of your team is a junior in JS so use on your own risk
const groupedData = data.reduce((groups, item) => {
const keyName = item[key];
return {
...groups,
[keyName]: [...(groups[keyName] || []), item],
};
}, {});
Log the result
The result of the method above will be the same, should be an object with properties corresponding to the grouped values:
console.log(groupedData);
{
female: [
{ name: 'Alice', age: 25, gender: 'female' },
{ name: 'Eve', age: 45, gender: 'female' }
],
male: [
{ name: 'Bob', age: 30, gender: 'male' },
{ name: 'Charlie', age: 35, gender: 'male' },
{ name: 'Dave', age: 40, gender: 'male' }
]
}
Method 2: Using the map() method
This method is used to group an array of objects into array of arrays not into an object, if you don't need an array of arrays feel free to go to the next section
The map() method can be used to group an array of objects into an array of arrays, where each inner array represents a group of objects with a common key value.
Step 1: Define the array of objects to be grouped:
const data = [
{ category: "fruit", name: "apple" },
{ category: "fruit", name: "banana" },
{ category: "vegetable", name: "carrot" },
{ category: "vegetable", name: "celery" },
{ category: "fruit", name: "orange" },
];
Step 2: Use the map()
method with Set()
to create a new array of unique keys:
const categories = [...new Set(data.map((item) => item.category))];
This will create an array of unique categories, which will be used as the basis for grouping the objects in the next step.
Step 3: Use the map()
method again to create a new array of arrays, with each inner array representing a group of objects with a common category value:
const groupedData = categories.map((category) => {
return data.filter((item) => item.category === category);
});
This will create an array of arrays, with each inner array representing a group of objects with a common category value.
Example:
const data = [
{ category: "fruit", name: "apple" },
{ category: "fruit", name: "banana" },
{ category: "vegetable", name: "carrot" },
{ category: "vegetable", name: "celery" },
{ category: "fruit", name: "orange" },
];
const categories = [...new Set(data.map((item) => item.category))];
const groupedData = categories.map((category) => {
return data.filter((item) => item.category === category);
});
console.log(groupedData);
// the result will be:
[
[
{ category: "fruit", name: "apple" },
{ category: "fruit", name: "banana" },
{ category: "fruit", name: "orange" },
],
[
{ category: "vegetable", name: "carrot" },
{ category: "vegetable", name: "celery" },
],
];
You can learn more about Array.prototype.map()
and Set()
: Array.prototype.map(), JavaScript Set()
Method 3: Using forEach() to group an array of objects
The forEach() method can be used to group an array of objects into an object with properties corresponding to the grouped values.
const persons = [
{ name: "John", age: 30 },
{ name: "Jane", age: 25 },
{ name: "Alice", age: 30 },
{ name: "Bob", age: 25 },
];
const grouped = {};
persons.forEach((person) => {
const age = person.age;
if (!grouped[age]) {
grouped[age] = [person];
} else {
grouped[age].push(person);
}
});
console.log(grouped);
// Output:
// {
// '30': [
// { name: 'John', age: 30 },
// { name: 'Alice', age: 30 }
// ],
// '25': [
// { name: 'Jane', age: 25 },
// { name: 'Bob', age: 25 }
// ]
// }
Method 4: Using for or for...of loop
Loop approach is useful when you need to group an array of objects in a custom way. However, using built-in methods is usually more concise and easier to read, especially for simple grouping operations.
const persons = [
{ name: "John", age: 30 },
{ name: "Jane", age: 25 },
{ name: "Alice", age: 30 },
{ name: "Bob", age: 25 },
];
const grouped = {};
for (let i = 0; i < persons.length; i++) {
const person = persons[i];
const age = person.age;
if (!grouped[age]) {
grouped[age] = [];
}
grouped[age].push(person);
}
console.log(grouped);
// {
// '25': [ { name: 'Jane', age: 25 }, { name: 'Bob', age: 25 } ],
// '30': [ { name: 'John', age: 30 }, { name: 'Alice', age: 30 } ]
// }
In this example, we use a for
loop to iterate through the persons array. For each person object in the array, we check if a key with the person
's age
already exists in the grouped
object. If not, we create a new empty array for that age
group. We then push the current person object into the appropriate age group array.
const persons = [
{ name: "John", age: 30 },
{ name: "Jane", age: 25 },
{ name: "Alice", age: 30 },
{ name: "Bob", age: 25 },
];
// Using loop methods
const grouped = {};
for (const person of persons) {
if (!grouped[person.age]) {
grouped[person.age] = [];
}
grouped[person.age].push(person);
}
console.log(grouped);
// {
// '25': [ { name: 'Jane', age: 25 }, { name: 'Bob', age: 25 } ],
// '30': [ { name: 'John', age: 30 }, { name: 'Alice', age: 30 } ]
// }
We then loop through the persons
array using a for...of
loop. For each person object in the array, we check if a key with the person's age
already exists in the grouped
object. If not, we create a new empty array for that age
group. We then push the current person object into the appropriate age
group array.
Method 5: Using array.group() and array.groupToMap()
Make sure to include a polyfills before using array.group
and array.groupToMap
. These methods are not yet available without polyfill
Array.prototype.group
and Array.prototype.groupToMap
are in Stage 3: See Proposal Array Grouping
A polyfills for those methods are available in core-js
Array.prototype.group
and Array.prototype.groupToMap
are built-in methods to group an array of objects:
Array.prototype.group to Group an array of objects
import "core-js/actual/array/group.js";
// or just
// import "core-js/actual"
const persons = [
{ name: 'John', age: 30 },
{ name: 'Jane', age: 25 },
{ name: 'Alice', age: 30 },
{ name: 'Bob', age: 25 }
];
const grouped = persons.group(item => item.age > 28 ? 'older' : 'younger')
The result will be
{
older: [ { name: 'John', age: 30 }, { name: 'Alice', age: 30 } ],
younger: [ { name: 'Jane', age: 25 }, { name: 'Bob', age: 25 } ]
}
Array.prototype.groupToMap to Group an array of objects
Note that this method return a Map() not an Array or Object
import "core-js/actual/array/group-to-map.js";
// or just
// import "core-js/actual"
const persons = [
{ name: "John", age: 30 },
{ name: "Jane", age: 25 },
{ name: "Alice", age: 30 },
{ name: "Bob", age: 25 },
];
const grouped = persons.groupToMap((item) =>
item.age > 28 ? "older" : "younger"
);
const older = grouped.get("older");
console.log(older)
// [ { name: 'John', age: 30 }, { name: 'Alice', age: 30 } ]
const younger = grouped.get("younger");
console.log(younger)
// [ { name: 'Jane', age: 25 }, { name: 'Bob', age: 25 } ]
Note that these methods are still experimental and not available in most browsers, so you'll need to include polyfills to use them.
This page was updated on -
Found an error or have feedback on our docs?
Create an issue on GitHub and let us know! Your input helps improve our documentation for everyone in the community.
Report error, send feedback on Github