我有一个嵌套的对象数组,我想对ID进行分组并形成一个新数组。这是我的数组:
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 }] }
]
我可以展平整个数组,但这似乎不是正确的方法。
我的新数组应如下所示:
result = [
comapny_6: [
{
name: 'a',
age: 10,
desc: 'test1'
},
],
comapny_10: [
{
name: 'a',
age: 10,
desc: 'testa'
},
{
name: 'c',
age: 40,
desc: 'test3'
}
],
company_30 :[
{
name: 'b',
age: 20,
desc: 'test2'
},
{
name: 'c',
age: 40,
desc: 'testc'
}
]
]
我愿意就最终数据结构的外观提出建议。最重要的是我想要groupBy id,以便我了解有关每个公司的信息。
答案 0 :(得分:1)
您可以使用state.finalWord
遍历数组并构造所需的对象输出。使用struct Iter
{
promise_handle handle = nullptr;
HelloWorldState state;
reference operator * () const { return state.currentWord; }
pointer operator -> () const { return std::addressof(operator*()); }
bool operator == (const Iter& other) { return !handle == !other.handle; }
bool operator != (const Iter& other) { return !(*this == other); }
Iter() = default;
Iter(promise_handle handle)
: handle(handle)
{
next();
}
Iter& operator ++()
{
if (!handle)
return *this;
next();
return *this;
}
void next()
{
if (!handle)
return;
try {
handle.resume();
if (!handle.done())
state = handle.promise().state;
else {
handle = nullptr;
}
} catch (...) {
std::cerr << "@%$#@%#@$% \n";
}
}
};
遍历reduce
forEach
答案 1 :(得分:1)
您可以先使用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;
})
答案 2 :(得分:0)
您可以使用Array.reduce来实现这一目标,并可以通过Array.forEach来实现像这样的一系列公司内部的目标:
let data = [ { 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 }] } ]
let result = data.reduce((r,{ name, age, company }) => {
company.forEach(({ id, desc }) =>
r[`company_${id}`] = (r[`company_${id}`] || []).concat({ name, age, desc }))
return r
}, {})
console.log(result)