#angular #typescript #group-by
Вопрос:
У меня есть список объектов, подобных этому:
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]
}
];
Я хочу сгруппировать мой dishes
по category
, поэтому я хочу этот вывод:
{
'Breakfast': [
{
name: 'Burger',
category: ['Breakfast', 'Dinner']
},
{
name: 'Cereal with milk',
category: ['Breakfast']
}
],
'Dinner': [
{
name: 'Burger',
category: ['Breakfast', 'Dinner']
},
],
'Supper': [
{
name: 'Chips',
category: ['Supper']
},
],
};
Ответ №1:
Что-то вроде этого:
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 resu<
}
groupBy((dish) => dish.category, dishes);
Ответ №2:
Отказ от ответственности
StackOverflow не предназначен для обеспечения внештатного программирования, это больше касается преподавания и обучения 🙂
Что вам нужно
Поэтому вот инструменты, которые вам нужны:
- Документация для
Array.prototype.reduce()
- Документация для расширенного синтаксиса (
...
)
(более конкретно, разделы «Распространение в литералах массива» и «Распространение в литералах объектов») - Документация для нулевого объединяющего оператора (
??
)
(на самом деле это не обязательно, но всегда полезно знать)
Что вы хотите
И на всякий случай, вот ответ, который вы хотите:
dishes.reduce(
(res, dish) => dish.category.reduce((acc, meal) => ({ ...acc, [TypeOfMeal[meal]]: [...(acc[TypeOfMeal[meal]] ?? []), dish] }), res),
{} as { [key: string]: Dish[] },
)
Я думаю, вам действительно может быть лучше сохранить ключи вашего результирующего набора, TypeOfMeal
а не string
представление enum
.
Просто попросите их «перевести», когда вам нужно их представить!
dishes.reduce(
(res, dish) => dish.category.reduce((acc, meal) => ({ ...acc, [meal]: [...(acc[meal] ?? []), dish] }), res),
{} as { [key in TypeOfMeal]: Dish[] },
)