问题描述
我正在尝试展平数组。
我有以下 4 个元素的输入JSON数组:
[
{
"nestedObj": {
"id":12
}
},{
"nestedObj": {
"id":555
}
},{
"nestedObj" :{
"id":771
}
}
]
我想将其转换为一个数组数组,其中每个子数组都将相同的nestedObj.id
元素组合在一起。
我可以假定初始JSON按nestedObj.id
排序。
在上面的示例中,第二个元素和第三个元素的id
的{{1}}是相同的(nestedObj
),因此这些元素将被分组为一个子数组。
这将是结果,该数组仅包含 3 个子数组元素:
555
这是让我得到想要的代码:
[
[{
"nestedObj": {
"id":12
}
}],[{
"nestedObj": {
"id":555
}
},{
"nestedObj": {
"id":555
}
}],[{
"nestedObj" :{
"id":771
}
}]
]
但是正如您所看到的,代码非常具有声明性。从功能编程的角度来看,它不是非常像JavaScript。
如何使用例如减少还是其他“现代JS”技术?
解决方法
只需将对象分组。
let array = [{ nestedObj: { id: 12 } },{ nestedObj: { id: 555 } },{ nestedObj: { id: 771 } }],result = Object.values(array.reduce((r,o) => {
(r[o.nestedObj.id] = r[o.nestedObj.id] || []).push(o);
return r;
},{}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
,
您可以使用函数reduce
按ID分组,使用函数Object.values
提取分组的值,最后使用map
数组构建所需的输出。
这是假设我们只有一个名为nestedObj
let arr = [{ nestedObj: { id: 12 } },result = Object.values(arr.reduce((a,{nestedObj: {id}}) => {
(a[id] || (a[id] = [])).push(id);
return a;
},{})).map(r => r.map(id => ({nestedObj: {id}})));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
,
使用地图将具有相同ID的项目分组,然后从地图中获取最终值
const data = [{ nestedObj: { id: 12 } },{ nestedObj: { id: 771 } }]
const map = new Map;
data.forEach(o => {
const {nestedObj:{id}} = o;
map.has(id) ? map.get(id).push(o) : map.set(id,[o]);
});
console.log([...map.values()])