Code recipe: Writing JavaScript groupBy() function

How to write a custom function that groups an array of objects by key or property

Posted on April 24, 2021


Sometimes, you may need to group an array of objects by a specific key or property value.

For example, you may want to group an array of movies by their release year as follows:

const movies = [
  { title: "Sonic the Hedgehog", year: 2020 },
  { title: "Mulan", year: 2020 },
  { title: "Godzilla vs. Kong", year: 2021 },
];

const moviesByYear = groupBy(movies, "year"); // TODO: implement groupBy()

The values stored in moviesByYear should be as follows:

const moviesByYear = {
  2020: [
    { title: "Sonic the Hedgehog", year: 2020 },
    { title: "Mulan", year: 2020 },
  ],
  2021: [{ title: "Godzilla vs. Kong", year: 2021 }],
};

This tutorial will help you to write the groupBy() function that produces the output above.

To write a function that will group an array of objects by its key value, you need to use the array reduce() method to iterate over the array and put each array element into the right place.

First, create a function named groupBy() that accepts an array and a string. In the following code example, the parameter arr is for passing the array of objects, while criteria will be for the property which the elements will be grouped by:

function groupBy(arr, criteria) { }

Then, you need to call the reduce() method on the arr variable, with an empty object {} as the accumulator’s starting value:

function groupBy(arr, criteria) {
  const newObj = arr.reduce(function (acc, currentValue) {

  }, {});
  return newObj;
}

Now you just need to write the reducer function. First, create an if block that will check if the accumulator already has a property with the same name as the current value’s criteria property.

If not, then assign a new property to the accumulator object named as current value’s criteria property:

function groupBy(arr, criteria) {
  const newObj = arr.reduce(function (acc, currentValue) {
    if (!acc[currentValue[criteria]]) {
      acc[currentValue[criteria]] = [];
    }
  }, {});
  return newObj;
}

Finally, you need to get the current value into the accumulator’s property by pushing currentValue into acc[currentValue[criteria]] as in the code below:

function groupBy(arr, criteria) {
  const newObj = arr.reduce(function (acc, currentValue) {
    if (!acc[currentValue[criteria]]) {
      acc[currentValue[criteria]] = [];
    }
    acc[currentValue[criteria]].push(currentValue);
    return acc;
  }, {});
  return newObj;
}

Now your groupBy() function is ready and you can reuse it to group different arrays of objects by one of their properties.

Here’s the complete code for you to try:

function groupBy(arr, criteria) {
  const newObj = arr.reduce(function (acc, currentValue) {
    if (!acc[currentValue[criteria]]) {
      acc[currentValue[criteria]] = [];
    }
    acc[currentValue[criteria]].push(currentValue);
    return acc;
  }, {});
  return newObj;
}

const movies = [
  { title: "Sonic the Hedgehog", year: 2020 },
  { title: "Mulan", year: 2020 },
  { title: "Godzilla vs. Kong", year: 2021 },
];

const moviesByYear = groupBy(movies, "year"); 

console.log(moviesByYear);
/*
{
  2020: [
    { title: "Sonic the Hedgehog", year: 2020 },
    { title: "Mulan", year: 2020 },
  ],
  2021: [{ title: "Godzilla vs. Kong", year: 2021 }],
};
*/

Feel free to use the code in your project 😉

Related articles:

Grab the free JavaScript book today 👍

Learn the building blocks of JavaScript programming language like data types, functions, objects, arrays and classes.

Use the knowledge from the book to build a small but solid program.

Learn more