Sun May 29 2022

Best way to group an array of objects by a key

A quick walkthrough on how to use the array reduce method to group objects in an array by any property value

Problem

I had a bunch of objects coming from a backend and needed to sort these objects by a property value of my choosing. So if the objects in the array looked like this

1const people = [
2 { name: "James", age: 21, sport: "rugby" },
3 { name: "Coco", age: 20, sport: "chess" },
4 { name: "Puff", age: 20, sport: "football" },
5];

I wanted to be able to have the below after passing this `people` array and specifying `sport` as the property key I wanted to sort these objects by.

1{
2 rugby: [{ name: "James", age: 21, sport: "rugby" }],
3 chess: [{ name: "Coco", age: 20, sport: "chess" }],
4 football: [{ name: "Puff", age: 20, sport: "football" }],
5};

Solution

A quick function that looks like below

1const groupBy = (data, groupByValue) => {
2 const groupedByData = data.reduce((accumalatedValue, currentValue) => {
3 // key is the property value of the passed groupByValue parameter
4 // since we passsed 'sports' as groupByValue, in the first iteration, the key would be 'rugby'
5 const key = currentValue[groupByValue];
6 // we look at whether the current accumalatedValue has a property with the key 'rugby'
7 if (!accumalatedValue[key]) {
8 // if there is no key called 'rugby' in accumalatedValue,
9 // we create a new property with an empty []
10 accumalatedValue[key] = [];
11 }
12 // since we now have a property with the key 'rugby',
13 // we basically push the currentValue object into its array
14 accumalatedValue[key].push(currentValue);
15 // then we return the accumalatedValue so that it can be used for the next iteration
16 return accumalatedValue;
17 }, {});
18 return groupedByData;
19};

Result

1const cleanedObject = groupBy(people, "sport");

`cleanedObject` now looks like this

1{
2 rugby: [{ name: "James", age: 21, sport: "rugby" }],
3 chess: [{ name: "Coco", age: 20, sport: "chess" }],
4 football: [{ name: "Puff", age: 20, sport: "football" }],
5};

Did this help you or do you know of any alternative ways of handling this? Hit me up in the comments below!

Comments