Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Group Array of JavaScript Objects by Key or Property Value

Group Array of JavaScript Objects by Key or Property Value

Implementation

const groupBy = key => array =>
  array.reduce((objectsByKeyValue, obj) => {
    const value = obj[key];
    objectsByKeyValue[value] = (objectsByKeyValue[value] || []).concat(obj);
    return objectsByKeyValue;
  }, {});

Or using an implicit return (slower):

const groupBy = key => array =>
  array.reduce(
    (objectsByKeyValue, obj) => ({
      ...objectsByKeyValue,
      [obj[key]]: (objectsByKeyValue[obj[key]] || []).concat(obj)
    }),
    {}
  );

Usage

const cars = [
  { brand: 'Audi', color: 'black' },
  { brand: 'Audi', color: 'white' },
  { brand: 'Ferarri', color: 'red' },
  { brand: 'Ford', color: 'white' },
  { brand: 'Peugot', color: 'white' }
];

const groupByBrand = groupBy('brand');
const groupByColor = groupBy('color');

console.log(
  JSON.stringify({
    carsByBrand: groupByBrand(cars),
    carsByColor: groupByColor(cars)
  }, null, 2)
);

Output

{
  "carsByBrand": {
    "Audi": [
      {
        "brand": "Audi",
        "color": "black"
      },
      {
        "brand": "Audi",
        "color": "white"
      }
    ],
    "Ferarri": [
      {
        "brand": "Ferarri",
        "color": "red"
      }
    ],
    "Ford": [
      {
        "brand": "Ford",
        "color": "white"
      }
    ],
    "Peugot": [
      {
        "brand": "Peugot",
        "color": "white"
      }
    ]
  },
  "carsByColor": {
    "black": [
      {
        "brand": "Audi",
        "color": "black"
      }
    ],
    "white": [
      {
        "brand": "Audi",
        "color": "white"
      },
      {
        "brand": "Ford",
        "color": "white"
      },
      {
        "brand": "Peugot",
        "color": "white"
      }
    ],
    "red": [
      {
        "brand": "Ferarri",
        "color": "red"
      }
    ]
  }
}
@JamieMason
Copy link
Author

JamieMason commented May 12, 2021

You want to convert that into [{"title":"AB", data:[{},{},{}]}, {"title":"BC", data:[{},{},{}]}]? can you give some more context on what you're trying to build? why would you want those empty objects for example?

@hussainahmad
Copy link

hussainahmad commented May 15, 2021

@JamieMason empty objects was just an example sorry for confusing you. , let assume I have a data

const cars = [
  { brand: 'Audi', color: 'black' },
  { brand: 'Audi', color: 'white' },
  { brand: 'Ferarri', color: 'red' },
  { brand: 'Ford', color: 'white' },
  { brand: 'Peugot', color: 'white' }
];

and I want to convert this array in to this array

[
  {
    "title": "Audi",
    "data": [
      {
        "brand": "Audi",
        "color": "black"
      },
      {
        "brand": "Audi",
        "color": "white"
      }
    ]
  },
  {
    "title": "Ferarri",
    "data": [
      {
        "brand": "Ferarri",
        "color": "red"
      }
    ]
  },
  {
    "title": "Ford",
    "data": [
      {
        "brand": "Ford",
        "color": "white"
      }
    ]
  },
  {
    "title": "Peugot",
    "data": [
      {
        "brand": "Peugot",
        "color": "white"
      }
    ]
  }
]

@JamieMason
Copy link
Author

JamieMason commented May 17, 2021

I think this should do it @hussainahmad:

const groupByBrand = groupBy('brand');
const carsByBrand = groupByBrand(cars);
const carBrands = Object.entries(carsByBrand).map(([title, data]) => ({ title, data }));

@hussainahmad
Copy link

hussainahmad commented May 17, 2021

Really Thanks to you @JamieMason , May God bless you

@JamieMason
Copy link
Author

JamieMason commented May 17, 2021

You're welcome

@MadhuriTank
Copy link

MadhuriTank commented May 19, 2021

@JamieMason, Thanks a lot!!! It is very useful !!!!

@scelloo-elegeonyejerome
Copy link

scelloo-elegeonyejerome commented Feb 2, 2022

@JamieMason Amazing work.. Quick One, how can one get the count of each group?

@JamieMason
Copy link
Author

JamieMason commented Feb 3, 2022

Like this @scelloo-elegeonyejerome:

const groupBy = (key) => (array) =>
  array.reduce((objectsByKeyValue, obj) => {
    const value = obj[key];
    objectsByKeyValue[value] = (objectsByKeyValue[value] || []).concat(obj);
    return objectsByKeyValue;
  }, {});

const cars = [
  { brand: 'Audi', color: 'black' },
  { brand: 'Audi', color: 'white' },
  { brand: 'Ferarri', color: 'red' },
  { brand: 'Ford', color: 'white' },
  { brand: 'Peugot', color: 'white' },
];

const groupByBrand = groupBy('brand');
const carsByBrand = groupByBrand(cars);

Object.entries(carsByBrand).forEach(([brand, cars]) => {
  console.log(`${cars.length} ${brand}`);
});

Outputs

"2 Audi"
"1 Ferarri"
"1 Ford"
"1 Peugot"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment