我有一个对象数组,其中每个对象都有一个属性,其值是另一个数组,如此
[
{
location: 'somewhere',
location_id: 1,
parts: [
{
part_id: 1,
description: 'foo',
qty: 1,
}
]
}
]
我需要将这些数组映射到像这样的单个数组
[
{
part_id: 1,
description: 'foo',
qty: 1
},
{
part_id: 2,
description: 'bar',
qty: 1
}
]
我尝试过使用reduce之类的
newArr: arr.reduce((a,b) => a.parts.concat(b.parts))
但是得到错误'无法读取未定义的属性concat。'我也尝试将reduce的initialValue参数作为空数组提供但是同样的错误。
作为奖励,我最终需要最终的数组不包含重复的部分:I.e。如果零件位于两个位置,它只会合并数量。
使用es6打开解决方案,但不需要修改原始数组
答案 0 :(得分:1)
如果您确定要映射数组而不是内部对象:
const input = [
{
location: 'somewhere',
location_id: 1,
parts: [
{
part_id: 1,
description: 'something'
}
]
},
{
location: 'somewhere2',
location_id: 22,
parts: [
{
part_id: 2,
description: 'something'
}
]
}
];
const mapped = input.map(outerObj => outerObj.parts[0]);
console.log(mapped);

答案 1 :(得分:1)
这会将所有零件对象添加到基础中并删除零件数组。它将修改旧对象。
let arr = [
{
location: 'somewhere',
location_id: 1,
parts: [
{
part_id: 1,
description: 'something'
}
]
}
]
arr.map(m => {
m.parts.forEach(p => Object.assign(m, p))
delete m.parts;
})
console.log(arr);
答案 2 :(得分:1)
您可以使用array#reduce
首先加入每个对象的所有parts
数组。然后使用array#reduce
对part_id
和description
上的结果数组中的每个对象进行分组,并为每个唯一对象总结qty
。然后从这个对象中获取所有值。
const input = [ { location: 'somewhere', location_id: 1, parts: [ { part_id: 1, description: 'foo', qty: 1 } ] }, { location: 'somewhere2', location_id: 22, parts: [ { part_id: 2, description: 'something', qty: 3 } ] }, { location: 'somewhere2', location_id: 22, parts: [ { part_id: 2, description: 'something', qty: 4 } ] } ],
result = Object.values(input.reduce((r, {parts}) => r.concat(parts),[])
.reduce((r,o) => {
r[`${o.part_id}_${o.description}`] = r[`${o.part_id}_${o.description}`] || {...o, qty: 0};
r[`${o.part_id}_${o.description}`].qty += o.qty;
return r;
},{}));
console.log(result);

答案 3 :(得分:1)
此解决方案使用reduce和forEach将子数组中的所有对象合并为Map,其中part_d
为关键,qty
为合计数量的结果。找到新的part_id
后,spreading部件会将新对象创建为新对象,并将qty
覆盖为0。
然后通过spreading Map.values()
迭代器将地图转换回数组:
const data = [{"location":"somewhere","location_id":1,"parts":[{"part_id":1,"description":"foo","qty":1}]},{"location":"somewhere2","location_id":2,"parts":[{"part_id":1,"description":"foo","qty":3},{"part_id":2,"description":"bar","qty":1}]}];
const result = [...
data.reduce((r, { parts }) => {
(parts || []).forEach((o) => {
r.has(o.part_id) || r.set(o.part_id, { ...o, qty: 0 });
r.get(o.part_id).qty += o.qty;
});
return r;
}, new Map())
.values()];
console.log(result);

答案 4 :(得分:0)
此问题可能有两种情况:
每个位置在零件数组下都有单个对象。
<强>样本强>
let jsonObj = [
{
location: 'somewhere',
location_id: 1,
parts: [
{
part_id: 1,
description: 'foo',
qty: 1,
}
]
},
{
location: 'somewhere',
location_id: 2,
parts: [
{
part_id: 2,
description: 'foo',
qty: 1,
}
]
}
];
let res = jsonObj.map(obj => obj.parts[0]);
console.log(res);
单个位置在parts数组下有多个对象。
<强>样本强>
let jsonObj = [
{
location: 'somewhere',
location_id: 1,
parts: [
{
part_id: 1,
description: 'foo',
qty: 1,
},
{
part_id: 2,
description: 'foo',
qty: 1,
}
]
}
];
let res = jsonObj[0].parts;
console.log(res);
答案 5 :(得分:0)
我也有类似的情况。对我有用的是定义一个新数组,然后从一个双映射函数内部定义array.push(part)
:
const input = [{
location: 'somewhere',
location_id: 1,
parts: [{
part_id: 1,
description: 'something'
},
{
part_id: 2,
description: 'something'
}
]
},
{
location: 'somewhere2',
location_id: 22,
parts: [{
part_id: 3,
description: 'something'
},
{
part_id: 4,
description: 'something'
}
]
}
];
如果这是您的输入。
var list = []
input.map(item => {
item.parts.map(part => {
list.push(part);
});
});