将平面定义的树转换为深度树JavaScript
对于输入平面树:将平面定义的树转换为深度树JavaScript,javascript,lodash,Javascript,Lodash,对于输入平面树: let input = [{ levelId: '1' }, { levelId: '1.1' }, { levelId: '1.1.1' }, { levelId: '1.2' }, { levelId: '2' }, { levelId: '2.1.1' } ] 将其转换为多级树的最佳方式是什么,其中levelId定义树的级别:
let input = [{
levelId: '1'
}, {
levelId: '1.1'
}, {
levelId: '1.1.1'
}, {
levelId: '1.2'
}, {
levelId: '2'
}, {
levelId: '2.1.1'
}
]
将其转换为多级树的最佳方式是什么,其中levelId定义树的级别:
let output = [{
levelId: '1',
children: [{
levelId: '1.1',
children: [{
levelId: '1.1.1'
}
]
}
]
}, {
levelId: '2',
children: [{
levelId: '2.1.1'
}
]
}
]
使用Lodash。我首先根据对象级别对数组进行排序,然后创建一个中间对象,用于将每个级别id映射到对象本身,并从中间对象中找到其父对象。然后我输出一个数组,其中的对象没有父对象 希望这有帮助 变量输入=[ { levelId:'1' }, { levelId:'1.1' }, { levelId:'1.1.1' }, { levelId:'1.2' }, { levelId:'2' }, { levelId:'2.1.1' }, { levelId:'3.1' }, { levelId:'3.1.1' } ]; 函数执行输入{ var temp={}; //按级别对数组排序,然后创建一个中间对象,该对象将级别id映射到级别对象,并映射到其父对象 input.sorta,b=>a.levelId.split..length-b.levelId.split..length.forEach lvl=>{ 温度[lvl.levelId]=lvl; iflvl.levelId.indexOf'.!=-1{ var parentLevelId=lvl.levelId; var父项=未定义; //逐级搜索父级,即3.1.1->3.1->3 做{ ifparentLevelId.indexOf'.=-1中断; parentLevelId=parentLevelId.substr0,parentLevelId.lastIndexOf。; parent=temp[parentLevelId]; }whiletypeof parent===“未定义” iftypeof parent!=“未定义”{ iftypeof parent.children===“未定义”{ parent.children=[]; } parent.children.pushlvl; lvl.parent=parent; } } }; //将没有父对象的根对象级别对象推送到输出数组 var输出=[]; forvar键输入温度{ iftypeof temp[key].parent!=“未定义”{ 删除临时[键][父项]; }否则{ output.pushtemp[键]; } } 返回输出; } console.logJSON.stringifyexecinput,0,3 另一种方法: 在第一步中,根据在输入中找到的节点构建一棵树。 然后,在第二步中,重新组织其父节点存在于树中的所有节点。 代码:
这是否意味着这是一项要求?你似乎错过了你迄今为止尝试过的东西?当输入没有1但有1.1时会发生什么?@solomantam。1.1成为顶级。
let input = [{
levelId: '1'
}, {
levelId: '2.1.1'
}, {
levelId: '2.1.1.2.5'
}, {
levelId: '1.1'
}, {
levelId: '1.2'
}, {
levelId: '2'
}, {
levelId: '1.1.1.1.1'
}, {
levelId: '3.1.1.1.1'
}
]
console.log(JSON.stringify(treeify(input)))
function treeify(input) {
let built = {},
result = { levelId:"", children:[] };
// First pass: build the tree in the order you encounter the nodes:
buildTree();
// Second pass: look for children already having an ancestor
reorganize(result);
// For return value, start with list of top level nodes
return result.children
// --- First pass: build tree from flat list
function buildTree() {
for (let o of input) {
let parentId = getParentId(o.levelId);
addChild(built[parentId]||result,o);
built[o.levelId] = o;
}
}
// --- Second pass: switch parents if found
function reorganize(node) {
if (!("children" in node)) return;
// Backward loop, as items will be removed during the loop
for (let i=node.children.length-1;i>=0;i--) {
let c = node.children[i];
// Attach node to first ancestor found
for(let parentId = getParentId(c.levelId);parentId;parentId=getParentId(parentId)) {
if (parentId in built) {
if (built[parentId]==node) {
break; // Already in right position
}
addChild(built[parentId],c);
node.children.splice(i,1);
break;
}
}
}
// Do it recursively on all child nodes
node.children.forEach(reorganize);
}
// --- Insert a child
function addChild(parent,child) {
if (!("children" in parent)) {
parent.children = [];
}
parent.children.push(child);
}
// --- Determine parent id (by splitting off the last segment of the ID)
function getParentId(id) {
return id.replace(/^\d+$|\.\d+$/,"")
}
}