javascript - 根据给定条件创建嵌套 json 对象
问题描述
我有一个平面列表(对象数组),如下一个:
var myList = [
{id:1, name:"ABC", type:"level_1"},
{id:2, name:"XYZ", type:"level_1"},
{id:1, name:"ABC_level 2", type:"level_2", level_one_id:1},
{id:2, name:"XYZ_level 2", type:"level_2", level_one_id:2},
{id:1, name:"ABC_level 3", type:"level_3", level_two_id:1},
{id:2, name:"XYZ_level 3", type:"level_3", level_two_id:2},
];
然后,我必须以这样一种方式对它们进行分组,以便我可以创建一个层次结构(我试图在下面的代码行中做到这一点):
var myList = [
{id:1, name:"ABC", type:"level_1"},
{id:2, name:"XYZ", type:"level_1"},
{id:1, name:"ABC_level 2", type:"level_2", level_one_id:1},
{id:2, name:"XYZ_level 2", type:"level_2", level_one_id:2},
{id:1, name:"ABC_level 3", type:"level_3", level_two_id:1},
{id:2, name:"XYZ_level 3", type:"level_3", level_two_id:2},
];
var myNestedList = {
levels: []
};
//-----------pushing level1----------
myList.forEach((res => {
if (res.type == "level_1") {
myNestedList.levels.push(res);
}
}));
//-----------pushing level 2---------
myNestedList.levels.forEach((res) => {
myList.forEach((val) => {
if (val.type == "level_2" && val.level_one_id == res.id) {
res["level_2"] = [] || res["level_2"];
res["level_2"].push(val);
}
})
})
//-----------pushing level 3---------
myNestedList.levels.forEach((res) => {
res["level_2"].forEach((val) => {
myList.forEach((lastlevel) => {
if (lastlevel.type == "level_3" && lastlevel.level_two_id == val.id) {
val["level_3"] = [] || val["level_3"];
val["level_3"].push(lastlevel);
}
})
})
})
console.log(myNestedList);
虽然我能够实现结果,但我确信这段代码可以更精确和更有意义。我们可以在这里使用 lodash 并缩短这段代码吗?
任何帮助将非常感激。谢谢!
解决方案
您可以id
为对象获取一个虚拟唯一性并引用父母并在树中收集项目。
这种方法也适用于未排序的数据。
var data = [{ id: 1, name: "ABC", type: "level_1" }, { id: 2, name: "XYZ", type: "level_1" }, { id: 1, name: "ABC_level 2", type: "level_2", level_one_id: 1 }, { id: 2, name: "XYZ_level 2", type: "level_2", level_one_id: 2 }, { id: 1, name: "ABC_level 3", type: "level_3", level_two_id: 1 }, { id: 2, name: "XYZ_level 3", type: "level_3", level_two_id: 2 }],
tree = function (data) {
var t = {};
data.forEach(o => {
var level = o.type.match(/\d+$/)[0],
parent = o[Object.keys(o).filter(k => k.startsWith('level_'))[0]] || 0,
parentId = `${level - 1}.${parent}`,
id = `${level}.${o.id}`,
children = `level_${level}`;
Object.assign(t[id] = t[id] || {}, o);
t[parentId] = t[parentId] || {};
t[parentId][children] = t[parentId][children] || [];
t[parentId][children].push(t[id]);
});
return t['0.0'].level_1;
}(data);
console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }
推荐阅读
- gitlab - 如果仅在对 master 分支进行推送或合并时触发作业,则结合 gitlab ci 规则
- c++ - 链接到 cmake 项目中的动态链接库
- android - 背景视图但它一直闪烁
- angular - 使用枚举作为对象字面量的键
- r - RStudio 代码在 Windows 上运行,但相同的代码在 Linux 上失败
- java - 从选择查询中排除基于多列的行
- c++ - 在 NFS 挂载上读取文件时出现奇怪的 C++ 行为
- postgresql - Websphere 为 Postgresqs 创建数据源
- python - pip,查找过去某个时间最新版本的包
- mysql - 将 COUNT 值插入另一个表中的另一个特定行