唯一名称算法

421 阅读1分钟

唯一名称算法

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;

}