1. 程式人生 > 程式設計 >js將列表組裝成樹結構的兩種實現方式分享

js將列表組裝成樹結構的兩種實現方式分享

目錄
  • 前言
  • 背景介紹
  • 實現方案
  • 遞迴法
  • 資源
  • 總結

前言

工作中偶爾就會遇到後端同學丟來一個列表,要我們自己組裝成一個樹結構渲染到頁面上,本文以兩種不同方式探索生成樹的演算法思想。

image.png

背景介紹

可組裝成樹結構的陣列一般有以下幾個要素:

  • 當前節點id
  • parentId 當前節點的父節點id
  • children 子節點列表(可能不會在介面中返回,需要組裝時候自己加上)

原始結構:

js將列表組裝成樹結構的兩種實現方式分享

目標結構:

js將列表組裝成樹結構的兩種實現方式分享

關鍵就是一維陣列中通過parentId找到其對應的父節點並新增到父節點的children陣列中。

實現方案

最直接的方式就是遍歷陣列,並把找到的子節點逐一新增到父節點中

function listToTreeSimple(data) {
  const res = [];
  data.forEach((item) => {
    const parent = data.find((node) => node.id === item.parentId);
    if (parent) {
      parent.children = parent.children || [];
      parent.children.push(item);
    www.cppcns.com
} else { // * 根節點PQAXbj res.push(item); } }); return res; }

考慮進一步優化,使用雜湊表,以id為key儲存每個節點值,省去data.find計算

www.cppcns.com
function listToTree(data) {
  // * 先生成parent建立父子關係
  const obj = {};
  data.forEach((item) => www.cppcns.com{
    obj[item.id] = item;
  });
  // * obj -> {1001: {id: 1001,parentId: 0,name: 'AA'},1002: {...}}
  // console.log(obj,"obj")
  const parentList = [];
  data.forEach((item) => {
    const parent = obj[item.parentId];
    if (parent) {
      // * 當www.cppcns.com
前項有父節點 parent.children = parent.children || []; parent.children.push(item); } else { // * 當前項沒有父節點 -> 頂層 parentList.push(item); } }); return parentList; }

即便資料量很小,帶來的效能提升也是顯著的

js將列表組裝成樹結構的兩種實現方式分享

遞迴法

更有騷操作遞迴法,效能會很差,但程式碼會很酷