Вы можете сначала создать одномерный массив, используя flatMap()
, а затем использовать reduce()
для группировки
const mainArray = [
{ name: 'a',age: 10, company: [ { desc: 'test1' , id: 6 }, { desc: 'testa' , id: 10 }] },
{ name: 'b',age: 20, company: [ { desc: 'test2' , id: 30 }] },
{ name: 'c',age: 40, company: [ { desc: 'test3' , id: 10 }, { desc: 'testc' , id: 30 }] }
]
const flat = mainArray.flatMap(({company,...rest}) => company.map(a => ({...rest,...a})));
const res = flat.reduce((ac,{id,...rest}) => ((ac[`company_${id}`] || (ac[`company_${id}`] = [])).push(rest),ac),{})
console.log(res)
Объяснение
reduce()
- это метод, который возвращает одно значение после итерации по всему массиву.Аккумулятор, то есть ac
в вышеприведенном случае, устанавливается на пустой объект {}
(который является вторым аргументом, передаваемым функции)
В каждой итерации мы возвращаем обновленный аккумулятор, который становится ac
для следующей итерации.Поэтому мы возвращаем из функции следующее выражение
((ac[`company_${id}`] || (ac[`company_${id}`] = [])).push(rest),ac)
ac[
company _ $ {id} ]
использует обозначение в скобках, которое принимает выражение company_${id}
.Это то же самое, что и
ac["company_" + id]
В приведенной выше строке проверяется, существует ли ac[company_${id}]
в ac
, а затем push()
rest
в нем.
Если ac[company_${id}]
нетсозданные, но они устанавливают его в пустой массив []
, затем push()
rest
к нему.
В последней части используется оператор запятой
((ac[`company_${id}`] || (ac[`company_${id}`] = [])).push(rest),ac)
Приведенное выше целое выражение оценивается какпоследнее значение, разделенное запятой ,
, равное ac
.Таким образом, в каждой итерации мы помещаем rest
в соответствующий массив и возвращаем ac
в конце.Код эквивалентен
const res = flat.reduce((ac,{id,...rest}) => {
//check if company id doesnot exist as key in ac then set it empty array
if(!ac[`company_${id}`]) ac[`company_${id}`] = [];
//push rest(which will be an object with all the keys expect id)
ac[`company_${id}`].push(rest)
//at last return ac
return ac;
})