У меня есть массив объектов, который выглядит так:
[
{external_id: 1, items: [{k: 'v'}] },
{external_id: 2, items: [{k1: 'v1'}] },
{external_id: 1, items: [{k2: 'v2'}, {k3: 'v3'}] }
]
Что я хочу сделать, так это объединить вложенные массивы на основе external_id и вернуть «чистый массив», который будет выглядеть так:
[
{external_id: 1, items: [{k: 'v'}, {k2: 'v2'}, {k3: 'v3'}] },
{external_id: 2, items: [{k1: 'v1'}] }
]
Итак, мой вопрос: как это сделать без использования классического цикла for?
Массивы не имели бы length >= 10
Я настоятельно рекомендую вам прочитать документацию по массивам javascript: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… и основам работы с объектами: developer.mozilla.org/en-US. /docs/Learn/JavaScript/Objects/…
Вам придется зацикливаться. Вы можете зацикливаться с помощью for, forEach, map, reduce, find, ... и т. д., но вам придется зацикливаться.
Вот способ, который создает карту с ключом external_id, а затем заполняет эту карту элементами. Наконец, значения этой карты представляют результат:
let data = [{external_id: 1, items: [{k: 'v'}] },{external_id: 2, items: [{k1: 'v1'}] },{external_id: 1, items: [{k2: 'v2'}, {k3: 'v3'}] }];
let map = new Map(data.map(({external_id}) => [external_id, { external_id, items:[] }]));
data.forEach(o => map.get(o.external_id).items.push(...o.items));
let result = [...map.values()];
console.info(result);
Использование сокращения и сортировки
let data = [{
external_id: 1,
items: [{
k: 'v'
}]
},
{
external_id: 2,
items: [{
k1: 'v1'
}]
},
{
external_id: 1,
items: [{
k2: 'v2'
}, {
k3: 'v3'
}]
},
];
let ans = data
.sort(function(a, b) {
return a['external_id'] - b['external_id'];
})
.reduce((acc, currentObject) => {
const endObject = acc[acc.length - 1];
if (endObject && endObject['external_id'] === currentObject.external_id) {
endObject.items.push(...currentObject.items);
} else {
acc.push({ ...currentObject
});
}
return acc;
}, []);
console.info(ans);
Спасибо, это тоже хорошее решение. Хотел бы я отметить оба ответа принятыми :)
Использование другого объекта для группировки объектов с одним и тем же свойством external_id
let a = [
{external_id: 1, items: [{k: 'v'}] },
{external_id: 2, items: [{k1: 'v1'}] },
{external_id: 1, items: [{k2: 'v2'}, {k3: 'v3'}] }
]
let obj = {};
a.forEach( ({external_id, items}) => {
obj[external_id] ??= new Set;
items.map( i => {
obj[external_id].add(JSON.stringify(i));
});
});
a = Object.keys(obj).map( (n) => {
n = Number(n);
return {
external_id:n,
items: [...obj[n]].map(JSON.parse)
}
})
Какой длины массивы?