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)
}),
{}
);
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)
);
{
"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"
}
]
}
}
You could do this @chgad, you're right.
The reason for double arrow-functions (a function creator / a function which returns another function) is so we can do things like this:
so users of your module do this:
Instead of this:
Broadly speaking it's a matter of style or taste. It comes from a functional programming-like style of writing JS.
Really – the benefits of it aren't obvious or arguably even applicable in this little example, but generating functions can make for really reusable, readable code. You need to be careful though and develop a sense for knowing when doing this would be an upgrade and not a downgrade.
A rule of thumb would be to not do what I'm doing here, unless you're confident in how to generate and compose functions in a functional style.