我很难从给定的URL数组创建树。 主要目标是将网址分为多个部分,然后将其排列为父子对象。 例如,给定数组:
const data = [
{
'id': '1',
'name': '/home',
},
{
'id': '2',
'name': '/story',
},
{
'id': '3',
'name': '/story/summer-story',
},
{
'id': '4',
'name': '/story/summer-story/2019',
},
]
输出应为:
const tree = [
{
'id': '1',
'name' : '/home',
children: []
},
{
'id': '2',
'name': '/story',
'children': [
{
'id' : '3',
'name': '/story/summer-story',
'children': [
{
'id': '4',
'name': '/story/summer-story/2019'
}
]
},
]
}
]
我已经使用Javascript deriving a Tree from a set of URLs
中的示例创建了某种解决方案当URL有一个或两个段时,我目前的解决方案很好用。一旦它具有两个以上的段,它将在根级别上添加节点,而不是嵌套到下降的父节点中。
示例代码
export const addToTree = (node, treeNodes) => {
const parentNode = getTheParentNodeChildArray(node.name, treeNodes) || treeNodes;
parentNode.push({
title: node.title,
name: node.name,
children: []
});
};
export const getTheParentNodeChildArray = (path, treeNodes) => {
for (let i = 0; i < treeNodes.length; i++) {
const treeNode = treeNodes[i];
const lastSegment = getStringWithoutLastSegment(path);
const lastNode = getStringWithoutLastSegment(treeNode.name);
if (lastNode === lastSegment) {
return treeNode.children;
}
else if (treeNode.children.length > 0) {
let possibleParent = false;
treeNode.children.forEach(function(item) {
const lastSegmentPath = getStringWithoutLastSegment(path);
const lastSegmentItem = getStringWithoutLastSegment(item.name);
if (lastSegmentItem === lastSegmentPath) {
possibleParent = true;
return false;
}
});
if (possibleParent) {
return getTheParentNodeChildArray(path, treeNode.children);
}
}
}
};
export const createTree = (nodes) => {
const tree = [];
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i];
addToTree(node, tree);
}
return tree;
};
export const getStringWithoutLastSegment = (str) => {
const stringArray = str.split('/');
stringArray.pop();
return (stringArray.join('/'));
};
提前谢谢
答案 0 :(得分:2)
这可以直接在一个函数中完成。该方法涉及遍历要添加的所有节点,然后逐目录遍历树目录,并根据需要创建节点。最终结果不是一棵树,因为有多个根,但是在构造它时使用虚拟根会很有帮助。
const makeTree = data => {
const base = {children: []};
for (const node of data) {
const path = node.name.match(/\/[^\/]+/g);
let curr = base;
path.forEach((e, i) => {
const currPath = path.slice(0, i + 1).join("");
const child = curr.children.find(e => e.name === currPath);
if (child) {
curr = child;
}
else {
curr.children.push({
id: node.id, name: currPath, children: []
});
curr = curr.children[curr.children.length-1];
}
});
}
return base.children;
};
const data = [
{
'id': '1',
'name': '/home',
},
{
'id': '2',
'name': '/story',
},
{
'id': '3',
'name': '/story/summer-story',
},
{
'id': '4',
'name': '/story/summer-story/2019',
},
];
console.log(makeTree(data));