線性結構與樹形結構相互轉換(ES6實現)


前言

  當樹形結構的層級越來越深時,操作某一節點會變得越來越費勁,維護成本不斷增加。所以線性結構與樹形的相互轉換變得異常重要!

  首先,我們約定樹形結構如下:

node = {
  id: number,  // 數值
parentId: number, // 數值 name: string,
children: [] || null, // 用數組的方式保存子節點,適合更多業務場景 }

   線性結構:

list = [
   { id: number, parentId: number, name: string }, 
   { id: number, parentId: number, name: string },
];

特殊情況  

  上面的樹形結構並不是很完美,當遇到菜單或者分類等業務場景時,每個頂級節點的parentId約定為0,當存在多個頂級節點,顯得不是一個完整的樹。所以在這類特殊情況下,我們需要構造一個頂級節點。將菜單或者分類的原有頂級節點存儲至該節點的children中。 所以最后約定頂級節點如下。

root = null || {
  id: 0,
  parentId: null,
  children: [node1, node2, ...],  
}

線性結構與樹形結構相互轉換

  線性轉樹形:

function listConvertTree(list) {
  let root = null;
  if (list && list.length) {
    root = { id: 0, parentId: null, children: [] };
    const group = {};
    for (let index = 0; index < list.length; index += 1) {
      if (list[index].parentId !== null && list[index].parentId !== undefined) {
        if (!group[list[index].parentId]) {
          group[list[index].parentId] = [];
        }
        group[list[index].parentId].push(list[index]);
      }
    }
    const queue = [];
    queue.push(root);
    while (queue.length) {
      const node = queue.shift();
      node.children = group[node.id] && group[node.id].length ? group[node.id] : null;
      if (node.children) {
        queue.push(...node.children);
      }
    }
  }
  return root;
}

  樹形轉線性:

function treeConvertList(root) {
  const list = [];
  if (root) {
    const Root = JSON.parse(JSON.stringify(root));
    const queue = [];
    queue.push(Root);
    while (queue.length) {
      const node = queue.shift();
      if (node.children && node.children.length) {
        queue.push(...node.children);
      }
      delete node.children;
      if (node.parentId !== null && node.parentId !== undefined) {
        list.push(node);
      }
    }
  }
  return list;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM