我有一个带有孩子的数据树结构:
{ id: 1,
name: "Dog",
parent_id: null,
children: [
{
id: 2,
name: "Food",
parent_id: 1,
children: []
},
{
id: 3,
name: "Water",
parent_id: 1,
children: [
{
id: 4,
name: "Bowl",
parent_id: 3,
children: []
},
{
id: 5,
name: "Oxygen",
parent_id: 3,
children: []
},
{
id: 6,
name: "Hydrogen",
parent_id: 3,
children: []
}
]
}
]
}
如上数据所示,任何子数据对象都可以有更多子数据。这表示一个 DOM 结构,用户可以从中选择一个项目来添加一个子项。
我有来自 DOM 的所选项目的已知文本标题以及用户想要插入的数据。我无法找到一个递归算法,该算法允许我将新数据添加到树的正确级别。
这是我思考问题并尝试对其进行伪编码的列表:
输入:
- 树(上面的数据)
- 来自 DOM 中单击项目的 parentTitle
输出:
- 插入项目的树
脚步:
- 确定最高使用的 id 以了解下一个唯一 id 是什么
- 检查当前数据级别是否与父级标题匹配
- 如果匹配,则在新数据中设置 id 和 parent_id 并推送到父级的子级
- 如果不匹配,则检查当前级别数据是否有子级
- 如果当前级别有孩子需要为每个重复步骤 2+,直到找到匹配项
这是我的代码:
function askUserForNewItem(e) {
const tree = getTree(); // returns above tree data structure
const name = prompt( 'Enter new item’s name:' ); // user input to match and insert as new item in tree
const clickedTitle = getClickedTitle(e); // returns string title of clicked on item from DOM - for example "Dog" or "Bowl"
const parent = determineParent(tree, clickedTitle);
const parent_id = parent[0].id;
// TODO - needs to set real unique id (highest unused id)
const newId = 101; // hard coded for now, needs to be dynamic
// TODO - needs to insert into correct level of children array in tree
return tree.children.push({ id: newId, name, emoji, children: [], parent_id: parent_id });
}
function determineParent(tree, clickedTitle) {
if(tree.children.length === 0) {
return false;
}
let treeLevel = tree;
let parent = [];
while(treeLevel.children.length !== 0) {
parent = treeLevel.children.filter(child => child.name === clickedTitle);
if(parent.length !== 0) {
break;
}
else {
// what to do here to make this recursive?
}
}
return parent;
}
因此,如果用户在单击“狗”的添加按钮时键入“猫”,那么一个新对象
{
id: 7,
name: "Cat",
parent_id: 1,
children: []
}
将插入到数据树中第一级“Dog”对象的子项中。