在JavaScript中制作数组平面时,如何对匹配的嵌套数组子级进行分组



我从API接收数据,需要将其转换为具有分组属性的更平坦格式。

在这个例子中,我有一个不同轮胎特性的汽车制造商列表。我正在试着把每一个可用的轮胎尺寸/宽度组合在一起。如果两个属性匹配,我需要合并记录。

响应

[
{
carMake: 'Ford',
tires: [
{
brand: 'Dunlap',
otherKey: 'aaa',
size: 33,
width: 12,
},
{
brand: 'Good Year',
size: 33,
width: 12,
},
{
brand: 'Continental',
size: 33,
width: 11,
},
{
brand: 'Pirelli',
size: 32,
width: 12,
}
]
},
{
carMake: 'Chevy',
tires: [
{
brand: 'Dunlap',
size: 33,
width: 12,
},
]
}
]

期望结果

[
{
carMake: 'Ford',
otherKey: 'aaa',
brands: ['Dunlap', 'Good Year'],
size: 33,
width: 12,
},
{
carMake: 'Ford',
brands: ['Continental'],
size: 33,
width: 11,
},
{
carMake: 'Ford',
brands: ['Pirelli'],
size: 32,
width: 12,
},
{
carMake: 'Chevy',
brands: ['Dunlap'],
size: 33,
width: 12,
}
]

我尝试过的:

我试过同时使用flatMap和reduce,但我只能完成第一级。诚然,我并不是最擅长处理JS形状的人,因为我主要使用基于C的语言。

apiResponse.flatMap(({carMake, tires}) => tires.map((tire) => ({ carMake, ...tire })));
[{
carMake: 'Chevy',
brand: 'Dunlap',
size: 33,
width: 12,
}]

const apiResponse = [{"carMake":"Ford","tires":[{"brand":"Dunlap",otherKey:'aaa',"size":33,"width":12},{"brand":"Good Year","size":33,"width":12},{"brand":"Continental","size":33,"width":11},{"brand":"Pirelli","size":32,"width":12}]},{"carMake":"Chevy","tires":[{"brand":"Dunlap","size":33,"width":12}]}]
const r = apiResponse.flatMap(({carMake,tires})=>
Object.values(
tires.reduce((a,{brand,size,width,...other})=>{
let k = [carMake, size, width].join();
a[k] ??= {carMake, brands: [], size, width};
(a[k] = {...a[k], ...other}).brands.push(brand);
return a
},{})
)
)
console.log(r)

您可以首先使用find来查找具有相同尺寸、宽度和尺寸的轮胎;胭脂红。

如果不存在,则在结果数组中插入新对象,否则在现有对象中推送新品牌。类似这样的东西:

response = [
{
carMake: 'Ford',
tires: [{"brand":"Dunlap","size":33,"width":12},{"brand":"Good Year","size":33,"width":12},{"brand":"Continental","size":33,"width":11},{"brand":"Pirelli","size":32,"width":12}]
},
{
carMake: 'Chevy',
tires: [{"brand":"Dunlap","size":33,"width":12}]
}
]
result=[]
response.forEach(k=> {
k.tires.forEach(tire=> {
ans = result.find(o=> o.size==tire.size && o.width==tire.width && k.carMake==o.carMake)
if(ans){
ans.brand.push(tire.brand) //in-place array object update
}else{
result.push({ carMake: k.carMake, brand: [tire.brand], size: tire.size, width: tire.width})
}
})
})
console.log(result)