I have list of object like this:
enum TypeOfMeal {
Breakfast,
Dinner,
Supper
}
interface Dish {
name: string,
category: TypeOfMeal[],
}
const dishes: Dish[] = [
{
name: 'Burger',
category: [TypeOfMeal.Breakfast, TypeOfMeal.Dinner]
},
{
name: 'Chips',
category: [TypeOfMeal.Supper]
},
{
name: 'Cereal with milk',
category: [TypeOfMeal.Breakfast]
}
];
I want groupped my dishes
by category
, so i want this output:
{
'Breakfast': [
{
name: 'Burger',
category: ['Breakfast', 'Dinner']
},
{
name: 'Cereal with milk',
category: ['Breakfast']
}
],
'Dinner': [
{
name: 'Burger',
category: ['Breakfast', 'Dinner']
},
],
'Supper': [
{
name: 'Chips',
category: ['Supper']
},
],
};
CodePudding user response:
Something like this:
function groupBy<T>(
getKeys: (item: T) => (string | number | symbol)[],
items: T[]
): Record<string | number | symbol, T[]> {
const result: Record<string | number | symbol, T[]> = {};
for (const item of items) {
for (const key of getKeys(item)) {
if (!result[key]) {
result[key] = [];
}
result[key].push(item);
}
}
return result;
}
groupBy((dish) => dish.category, dishes);
CodePudding user response:
Disclaimer
StackOverflow isn't meant to provide freelance programming, it's more about teaching and learning :)
What you need
Therefore, here's the tools you need:
- Documentation for
Array.prototype.reduce()
- Documentation for Spread syntax (
...
)
(more specifically, the sections "Spread in array literals" and "Spread in object literals") - Documentation for the Nullish coalescing operator (
??
)
(not really necessary, but it's always good to know)
What you want
And just in case, here's the answer you want:
dishes.reduce(
(res, dish) => dish.category.reduce((acc, meal) => ({ ...acc, [TypeOfMeal[meal]]: [...(acc[TypeOfMeal[meal]] ?? []), dish] }), res),
{} as { [key: string]: Dish[] },
)
I reckon you may actually be better off keeping the keys of your resulting set as TypeOfMeal
rather than the string
representation of the enum
.
Just have them "translate" when you need to present them!
dishes.reduce(
(res, dish) => dish.category.reduce((acc, meal) => ({ ...acc, [meal]: [...(acc[meal] ?? []), dish] }), res),
{} as { [key in TypeOfMeal]: Dish[] },
)