как отсортировать объекты по массивам
есть массив объктов:
[
{category:1, product: 1},
{category:1, product: 2},
{category:1, product: 3},
{category:2, product: 4},
{category:2, product: 5},
{category:3, product: 6},
{category:4, product: 7}
]
нужно отсортировать массив по котегориям так чтобы на выходе был:
[
[
{category:1, product: 1},
{category:1, product: 2},
{category:1, product: 3}
],
[
{category:2, product: 4},
{category:2, product: 5},
],
[
{category:3, product: 6},
],
[
{category:4, product: 7}
]
]
сортировать нужно по категориям и массивы должны быть динамическими.
никак не пойму как решить, попытался отсортировать по возростанию числа категорий, потом найти первый и последний индекс определённых категорий и при помощ slice() отрезать нужные объекты, но такой способ думаю не оптимальный
Ответы (2 шт):
Можно использовать временную промежуточную структуру, чтобы сгруппировать объекты по нужному ключу, а потом преобразовать её в нужный формат. Так мы расходуем больше памяти, но немного экономим на времени, потому что не нужно постоянно искать нужное место для текущего элемента, обыскивая строящуюся окончательную структуру.
const data1 = [
{category:1, product: 1},
{category:1, product: 2},
{category:1, product: 3},
{category:2, product: 4},
{category:2, product: 5},
{category:3, product: 6},
{category:4, product: 7},
];
const temp = data1.reduce(
(acc, object) => {
if (!acc[object.category]) acc[object.category] = [];
acc[object.category].push(object);
return acc;
},
{},
);
const data2 = Object.values(temp);
console.log(data2);
Можно ещё использовать ключ как индекс массива и потом вычистить дыры. Правда из-за чистки дыр мы по сути тоже используем временную структуру и на это тоже уйдёт память и время)
const data1 = [
{category:1, product: 1},
{category:1, product: 2},
{category:1, product: 3},
{category:2, product: 4},
{category:2, product: 5},
{category:3, product: 6},
{category:4, product: 7},
];
const data2 = data1.reduce(
(acc, object) => {
if (!acc[object.category]) acc[object.category] = [];
acc[object.category].push(object);
return acc;
},
[],
).filter(Boolean);
console.log(data2);
А можно сразу вставлять элементы в нужные места.
const arr = [
{category:1, product: 1},
{category:1, product: 2},
{category:1, product: 3},
{category:2, product: 4},
{category:2, product: 5},
{category:3, product: 6},
{category:4, product: 7}
];
console.log(arr.reduce((acc, cur) => {
const idx = acc.findIndex(e => e[0].category === cur.category);
idx === -1 ? acc.push([cur]) : acc[idx].push(cur);
return acc;
}, []));