博客 / 詳情

返回

JS從扁平array轉tree

有時我們需要從扁平的數組結構(flat array),根據id,和pid構建出樹形數組結構(tree array),這種情形經常出現在嵌套的目錄結構,如下圖:

或者企業的部門架構,也會出現上面的類似結構。
類似上面的情景,假如我們有以下的數據:
let entries = [{
    "id": "12",
    "parentId": "0",
    "text": "Man",
    "level": "1",
    "children": null
  },
  {
    "id": "7",
    "parentId": "12",
    "text": "Other",
    "level": "2",
    "children": null
  },
  {
    "id": "8",
    "parentId": "7",
    "text": "Bird",
    "level": "3",
    "children": null
  },
  {
    "id": "9",
    "parentId": "0",
    "text": "Woman",
    "level": "1",
    "children": null
  },
  {
    "id": "11",
    "parentId": "9",
    "text": "Girl",
    "level": "2",
    "children": null
  }
];

我們期待通過一個算法,構建出下面的結構:

[
   {
      "id": "12",
      "parentId": "0",
      "text": "Man",
      "level": "1",
      "children": [
         {
            "id": "7",
            "parentId": "12",
            "text": "Other",
            "level": "2",
            "children": [
               {
                  "id": "8",
                  "parentId": "7",
                  "text": "Bird",
                  "level": "3",
                  "children": []
               }
            ]
         }
      ]
   },
   {
      "id": "9",
      "parentId": "0",
      "text": "Woman",
      "level": "1",
      "children": [
         {
            "id": "11",
            "parentId": "9",
            "text": "Girl",
            "level": "2",
            "children": []
         }
      ]
   }
]

也許我們可以想到,在遍歷數組的時候使用遞歸。沒錯可以解決問題,但是這種方式並不高效。

最近,在Stack Overflow上看到一個方法,感覺不錯,貼出來分享一下:

function list_to_tree(list) {
    var map = {}, node, roots = [], i;
    
    for (i = 0; i < list.length; i += 1) {
      map[list[i].id] = i;      // initialize the map
      list[i].children = [];    // initialize the children
    }
    
    for (i = 0; i < list.length; i += 1) {
      node = list[i];
      if (node.parentId !== "0") {
        // if you have dangling branches check that map[node.parentId] exists
        list[map[node.parentId]].children.push(node);
      } else {
        roots.push(node);
      }
    }
    return roots;
}

算法的複雜度是Θ(n log(n))。

如果使用遞歸,那麼複雜度是Θ(n^2)。如果數據集比較大,那麼執行的時間會很長。

user avatar columsys 頭像 jianqiangdepaobuxie 頭像 mulander 頭像 frontoldman 頭像 codeoop 頭像 layouwen 頭像 niaonao 頭像 notrynosuccess 頭像 codinger 頭像 yangyaya 頭像 hooray 頭像 jinl9s27 頭像
15 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.