关于tree结构相互转换

165 阅读1分钟

首先需要将一个一维数组根据他们之间的关联关系转为一个树形结构。
第一个想到的办法就是递归

let arr = [
{id:1, parent_id: 0, tag: '剪辑'},
{id: 2, parent_id: 1,  tag: "教程"},
{id: 3, parent_id: 1, tag: "成品"},
{id: 5, parent_id: 0,  tag: "剧情"},
{id: 6, parent_id: 5,  tag: "搞笑"}
]

function arrTotree(data, parentId= 0) {
    let tree = []
    data.map(item=> {
    if(item.parent_id === parentId) {
        item.children = arrTotree(data, item.id)
         tree.push({
         ...item
         })
     }
}
arrTotree(arr) // 就是一个包含children的树形结构了

当然递归的弊端就是当数据量过大时,你的页面一定会崩溃的。
所以可以采用第二种方法

function arrTotree(arr,rootId=0, parentId=0) {
const objMap = {}
const tree = []
for(const item of arr) {
  const id = item['id'] 
  const parentId = item['parent_id']
  // 查找是否已经存在map中
  objMap[id] = !objMap[id] ? item : {...item, ...objMap[id]}
  const treeItem =  objMap[id]
  if(parentId === rootId) {
    tree.push(treeItem)
  } else {
    if(!objMap[parentId]) {
      objMap[parentId] = {}
    }
    if(!objMap[parentId]['children']) {
      objMap[parentId]['children'] = []
    }
    objMap[parentId]['children'].push(treeItem)
  }
}
return tree
}

场景是这样的,现在已知树形结构,子节点的id,需要求出父节点的id及对应的tag。
其实就是倒着遍历,因为数据量不会太大,同样使用了递归来实现。

 // 根据子节点找到父节点
  let findParent = (array, id) => {
    let stack = [];
    let going = true;
    let walker = (array, id) => {
      array.forEach(item => {
        if (!going) return;
        stack.push(item['tag']);
        if (item['id'] === id) {
          going = false;
        } else if (item['children']) {
          walker(item['children'], id);
        } else {
          stack.pop();
        }
      });
      if (going) stack.pop();
    };
    walker(array, id);
    return stack.join('-');
  };
  
  findParent(arr,6) // 剧情-搞笑

最后感兴趣的朋友可以试着写一下第二种方法找父元素。