This fork of JamieMason's implementation changes the key
parameter to be an array of keys instead of just a single key. This makes it possible to group by multiple properties instead of just one.
const groupBy = keys => array =>
array.reduce((objectsByKeyValue, obj) => {
const value = keys.map(key => obj[key]).join('-');
objectsByKeyValue[value] = (objectsByKeyValue[value] || []).concat(obj);
return objectsByKeyValue;
}, {});
Click to see TypeScript version
/**
* Group array of objects by given keys
* @param keys keys to be grouped by
* @param array objects to be grouped
* @returns an object with objects in `array` grouped by `keys`
* @see <https://gist.github.com/mikaello/06a76bca33e5d79cdd80c162d7774e9c>
*/
const groupBy = <T>(keys: (keyof T)[]) => (array: T[]): Record<string, T[]> =>
array.reduce((objectsByKeyValue, obj) => {
const value = keys.map((key) => obj[key]).join('-');
objectsByKeyValue[value] = (objectsByKeyValue[value] || []).concat(obj);
return objectsByKeyValue;
}, {} as Record<string, T[]>);
const cars = [
{ brand: 'Audi', produced: '2016', color: 'black' },
{ brand: 'Audi', produced: '2017', color: 'white' },
{ brand: 'Ford', produced: '2016', color: 'red' },
{ brand: 'Ford', produced: '2016', color: 'white' },
{ brand: 'Peugot', produced: '2018', color: 'white' }
];
const groupByBrand = groupBy(['brand']);
const groupByColor = groupBy(['color']);
const groupByBrandAndYear = groupBy(['brand', 'produced']);
console.log(
JSON.stringify({
carsByBrand: groupByBrand(cars),
carsByColor: groupByColor(cars),
carsByBrandAndYear: groupByBrandAndYear(cars)
}, null, 2)
);
{
"carsByBrand": {
"Audi": [
{
"brand": "Audi",
"produced": "2016",
"color": "black"
},
{
"brand": "Audi",
"produced": "2017",
"color": "white"
}
],
"Ford": [
{
"brand": "Ford",
"produced": "2016",
"color": "red"
},
{
"brand": "Ford",
"produced": "2016",
"color": "white"
}
],
"Peugot": [
{
"brand": "Peugot",
"produced": "2018",
"color": "white"
}
]
},
"carsByColor": {
"black": [
{
"brand": "Audi",
"produced": "2016",
"color": "black"
}
],
"white": [
{
"brand": "Audi",
"produced": "2017",
"color": "white"
},
{
"brand": "Ford",
"produced": "2016",
"color": "white"
},
{
"brand": "Peugot",
"produced": "2018",
"color": "white"
}
],
"red": [
{
"brand": "Ford",
"produced": "2016",
"color": "red"
}
]
},
"carsByBrandAndYear": {
"Audi-2016": [
{
"brand": "Audi",
"produced": "2016",
"color": "black"
}
],
"Audi-2017": [
{
"brand": "Audi",
"produced": "2017",
"color": "white"
}
],
"Ford-2016": [
{
"brand": "Ford",
"produced": "2016",
"color": "red"
},
{
"brand": "Ford",
"produced": "2016",
"color": "white"
}
],
"Peugot-2018": [
{
"brand": "Peugot",
"produced": "2018",
"color": "white"
}
]
}
}
See playcode.io for example.
I'm glad you figured it out :-)