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)。如果数据集比较大,那么执行的时间会很长。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值