Группировка массива объектов
Имеется массив объектов. Необходимо сгруппировать его по одному из ключей объекта.
const foods = [
{id: 1, title: 'apple', type: 'fruit'},
{id: 2, title: 'banana', type: 'fruit'},
{id: 3, title: 'bird', type: 'meat'},
{id: 4, title: 'beer', type: 'drinks'},
{id: 5, title: 'cow', type: 'meat'},
]
Должен получиться следующий результат:
const foodTypes = [
{
type: 'fruit',
foods: [
{id: 1, title: 'apple', type: 'fruit'},
{id: 2, title: 'banana', type: 'fruit'},
]
},
{
type: 'meat',
foods: [
{id: 3, title: 'cow', type: 'meat'},
{id: 4, title: 'bird', type: 'meat'},
]
},
{
type: 'drinks',
foods: [
{id: 5, title: 'beer', type: 'drinks'},
]
},
]
Ответы (3 шт):
Автор решения: SABOTAGE
→ Ссылка
В result положим все совпадения по type, далее создадим шаблон обьекта, который будем добавлять в foodTypes, и каждый найденный результат в result будем добавлять в object.foods , в конце функция добавит наш обьект в foodTypes.
const foodTypes = [];
function groupMassive(value) {
const result = foods.filter((item) => {
return item.type.includes(value);
});
const object = {
type: "",
foods: [],
};
object.type = result[0].type;
result.forEach((item) => object.foods.push(item));
foodTypes.push(object);
}
groupMassive("fruit");
groupMassive("meat");
groupMassive("drinks");
Если хотим автоматизировать, то создадим вторую функцию которая вернёт готовый массив
function returnMassive(massive)
{
const types = massive.filter(item => item.type)
types.forEach(type => groupMassive(type))
}
returnMassive(foods)
Автор решения: Andrew
→ Ссылка
Вот рабочий вариант через reduce
const foods = [
{id: 1, title: 'apple', type: 'fruit'},
{id: 2, title: 'banana', type: 'fruit'},
{id: 3, title: 'bird', type: 'meat'},
{id: 4, title: 'beer', type: 'drinks'},
{id: 5, title: 'cow', type: 'meat'},
]
const grouper = key => array =>
Object.values(array.reduce((acc,val) => {
const property = val[key];
acc[property] = acc[property] || {
type: property,
foods: []
};
acc[property].foods.push(val);
return acc;
},{}))
console.log(JSON.stringify((grouper('type')(foods)), null,2))
Автор решения: smellyshovel
→ Ссылка
Более современный вариант с использованием Object.groupBy.
const foods = [
{id: 1, title: 'apple', type: 'fruit'},
{id: 2, title: 'banana', type: 'fruit'},
{id: 3, title: 'bird', type: 'meat'},
{id: 4, title: 'beer', type: 'drinks'},
{id: 5, title: 'cow', type: 'meat'},
]
const res = Object.entries(
Object.groupBy(foods, ({type}) => type))
.map(([type, foods]) => ({type, foods}));
console.log(res);