唯一名称算法
question:
已知有如下一个树状数据结构:
let tree = [
{
id: "1",
type: "parent",
name: "parent",
children: [
{
id: "2",
type: "button",
name: "button",
parent_id: "1"
},
{
id: "3",
type: "parent",
name: "parent_1",
parent_id: "1",
children: [
{
id: "4",
type: "button",
name: "button_1",
parent_id: "3"
}
]
},
{
id: "4",
type: "parent",
parent_id: "1",
name: "parent_3"
}
]
} ]
const insertNode = {
id: "8",
type: "parent",
parent_id: "1",
name: "button_3"
};
name字段的规则为整棵树不能重复,如果遇到重复,则添加_n作为结尾,如果因为删除某些节点,名字出现了空隙,比如tree中有button_1 和 button_3 但是没有button_2, 下一次插入时,需要优先使用button_2,而不是button_4.
请实现一个唯一名称算法,当向整颗树的任意children插入一个新的NODE时,可以保证NAME不重复。
name 是计划向tree中插入节点的name,比如 button tree 是整棵树
insertObject(insertNode, tree) {
let names = {};
this.deepNode(tree, names);
insertNode.name = this.getNodeName(insertNode.name,names);
this.insertAction(insertNode, tree);
return tree;
},
// 遍历整颗树,并且将名称对象化
deepNode(tree, names) {
tree.map(item => {
const name_index = item.name.split("_");
if (names[name_index[0]]) {
if(name_index[1]){
names[name_index[0]][name_index[1]]=item.name;
}else{
names[name_index[0]][0]=item.name;
}
} else {
names[name_index[0]] = [item.name];
}
if (item.children && item.children.length) {
this.deepNode(item.children, names);
}
});
},
//获取当前要插入对象的名称
getNodeName(name, names){
const nodeName = name.split("_");
if (nodeName[0]) {
if (names[nodeName[0]]) {
if (names[nodeName[0]].length) {
let nullIndex = 0;
for(let index of names[nodeName[0]].keys()){
if(!names[nodeName[0]][index]){
nullIndex = index;
}
}
if(nullIndex){
return `${nodeName[0]}_${nullIndex}`;
}else{
return `${nodeName[0]}_${names[nodeName[0]].length}`;
}
} else {
names[nodeName[0]] = [];
names[nodeName[0]].push(nodeName[0]);
return nodeName;
}
} else {
return nodeName;
}
}
},
// 进行插入操作
insertAction(insertNode, tree){
tree.map(item => {
if(item.id === insertNode.parent_id){
if(insertNode.name.split('_')[1]){
// item.children.splice(insertNode.name.split('_')[1], 0, insertNode);
item.children.push(insertNode);
}else{
item.children = [];
item.children.push(insertNode);
}
}
});
return tree;
}