JS 将扁平后的数据 恢复成 树结构

用 JS 将扁平后的数据 恢复成 树结构

已扁平化后的 省市区 为例子:

扁平后的数据

plain-area.json

[
  {
    "id": 4744,
    "name": "中国",
    "pid": 0
  },
  {
    "id": 1,
    "name": "北京",
    "pid": 4744
  },
  {
    "id": 72,
    "name": "朝阳区",
    "pid": 1
  },
  {
    "id": 55653,
    "name": "八里庄街道",
    "pid": 72
  },
  {
    "id": 4139,
    "name": "北苑",
    "pid": 72
  },
  {
    "id": 55654,
    "name": "常营地区",
    "pid": 72
  },
  {
    "id": 2901,
    "name": "昌平区",
    "pid": 1
  },
  {
    "id": 55548,
    "name": "百善镇",
    "pid": 2901
  },
  {
    "id": 55549,
    "name": "北七家镇",
    "pid": 2901
  },
  {
    "id": 55550,
    "name": "城北街道",
    "pid": 2901
  },
  {
    "id": 2806,
    "name": "石景山区",
    "pid": 1
  },
  {
    "id": 54707,
    "name": "八宝山街道",
    "pid": 2806
  },
  {
    "id": 4188,
    "name": "八大处科技园区",
    "pid": 2806
  },
  {
    "id": 54708,
    "name": "八角街道",
    "pid": 2806
  },
  {
    "id": 4,
    "name": "重庆",
    "pid": 4744
  },
  {
    "id": 48131,
    "name": "璧山区",
    "pid": 4
  },
  {
    "id": 58515,
    "name": "璧城街道",
    "pid": 48131
  },
  {
    "id": 58516,
    "name": "璧泉街道",
    "pid": 48131
  },
  {
    "id": 48192,
    "name": "八塘镇",
    "pid": 48131
  },
  {
    "id": 48202,
    "name": "巴南区",
    "pid": 4
  },
  {
    "id": 52490,
    "name": "城区",
    "pid": 48202
  },
  {
    "id": 48372,
    "name": "石龙镇",
    "pid": 48202
  },
  {
    "id": 48371,
    "name": "石滩镇",
    "pid": 48202
  },
  {
    "id": 48203,
    "name": "北碚区",
    "pid": 4
  },
  {
    "id": 54800,
    "name": "北温泉街道",
    "pid": 48203
  },
  {
    "id": 54799,
    "name": "朝阳街道",
    "pid": 48203
  },
  {
    "id": 48246,
    "name": "澄江镇",
    "pid": 48203
  },
  {
    "id": 16,
    "name": "福建",
    "pid": 4744
  },
  {
    "id": 1303,
    "name": "福州市",
    "pid": 16
  },
  {
    "id": 1305,
    "name": "长乐区",
    "pid": 1303
  },
  {
    "id": 53259,
    "name": "城区",
    "pid": 1305
  },
  {
    "id": 48927,
    "name": "古槐镇",
    "pid": 1305
  },
  {
    "id": 59088,
    "name": "航城街道",
    "pid": 1305
  },
  {
    "id": 48713,
    "name": "仓山区",
    "pid": 1303
  },
  {
    "id": 48747,
    "name": "城门镇",
    "pid": 48713
  },
  {
    "id": 51478,
    "name": "城区",
    "pid": 48713
  },
  {
    "id": 59132,
    "name": "仓前街道",
    "pid": 48713
  },
  {
    "id": 48715,
    "name": "福清市",
    "pid": 1303
  },
  {
    "id": 48902,
    "name": "城头镇",
    "pid": 48715
  },
  {
    "id": 51480,
    "name": "城区",
    "pid": 48715
  },
  {
    "id": 48910,
    "name": "东瀚镇",
    "pid": 48715
  },
  {
    "id": 1362,
    "name": "龙岩市",
    "pid": 16
  },
  {
    "id": 1365,
    "name": "长汀县",
    "pid": 1362
  },
  {
    "id": 44995,
    "name": "城区",
    "pid": 1365
  },
  {
    "id": 45007,
    "name": "策武镇",
    "pid": 1365
  },
  {
    "id": 44997,
    "name": "大同镇",
    "pid": 1365
  },
  {
    "id": 1369,
    "name": "连城县",
    "pid": 1362
  },
  {
    "id": 45128,
    "name": "北团镇",
    "pid": 1369
  },
  {
    "id": 45126,
    "name": "城区",
    "pid": 1369
  },
  {
    "id": 45137,
    "name": "隔川乡",
    "pid": 1369
  },
  {
    "id": 1368,
    "name": "上杭县",
    "pid": 1362
  },
  {
    "id": 45065,
    "name": "白砂镇",
    "pid": 1368
  },
  {
    "id": 45078,
    "name": "步云乡",
    "pid": 1368
  },
  {
    "id": 45075,
    "name": "茶地镇",
    "pid": 1368
  },
  {
    "id": 1370,
    "name": "宁德市",
    "pid": 16
  },
  {
    "id": 1377,
    "name": "屏南县",
    "pid": 1370
  },
  {
    "id": 46200,
    "name": "屏城乡",
    "pid": 1377
  },
  {
    "id": 46199,
    "name": "长桥镇",
    "pid": 1377
  },
  {
    "id": 46195,
    "name": "城区",
    "pid": 1377
  },
  {
    "id": 1373,
    "name": "福鼎市",
    "pid": 1370
  },
  {
    "id": 46275,
    "name": "白琳镇",
    "pid": 1373
  },
  {
    "id": 46274,
    "name": "磻溪镇",
    "pid": 1373
  },
  {
    "id": 51502,
    "name": "城区",
    "pid": 1373
  },
  {
    "id": 1372,
    "name": "福安市",
    "pid": 1370
  },
  {
    "id": 46258,
    "name": "坂中畲族乡",
    "pid": 1372
  },
  {
    "id": 55509,
    "name": "城北街道",
    "pid": 1372
  },
  {
    "id": 55508,
    "name": "城南街道",
    "pid": 1372
  }
]

通过递归生成树

const plainArea = require('./plain-area.json')

/**
 * 递归找 children
 * @param {[]} plain - 原始扁平化后的树数据
 * @param {number} pid - 父级id (parent id)
 * @return {*[]}
 */
function findChildren(plain = [], pid) {
  const children = plain.filter(area => area.pid === pid)
  if (!children.length) {
    return []
  }
  children.forEach(area => {
    area.children = findChildren(plain, area.id)
  })
  return children
}

function main() {
  const tree = findChildren(plainArea, 0)
  console.log('树已生成', tree)
}

main()

生成的 树结构体数据

[
  {
    "id": 4744,
    "name": "中国",
    "pid": 0,
    "children": [
      {
        "id": 1,
        "name": "北京",
        "pid": 4744,
        "children": [
          {
            "id": 72,
            "name": "朝阳区",
            "pid": 1,
            "children": [
              {
                "id": 55653,
                "name": "八里庄街道",
                "pid": 72,
                "children": []
              },
              {
                "id": 4139,
                "name": "北苑",
                "pid": 72,
                "children": []
              },
              {
                "id": 55654,
                "name": "常营地区",
                "pid": 72,
                "children": []
              }
            ]
          },
          {
            "id": 2901,
            "name": "昌平区",
            "pid": 1,
            "children": [
              {
                "id": 55548,
                "name": "百善镇",
                "pid": 2901,
                "children": []
              },
              {
                "id": 55549,
                "name": "北七家镇",
                "pid": 2901,
                "children": []
              },
              {
                "id": 55550,
                "name": "城北街道",
                "pid": 2901,
                "children": []
              }
            ]
          },
          {
            "id": 2806,
            "name": "石景山区",
            "pid": 1,
            "children": [
              {
                "id": 54707,
                "name": "八宝山街道",
                "pid": 2806,
                "children": []
              },
              {
                "id": 4188,
                "name": "八大处科技园区",
                "pid": 2806,
                "children": []
              },
              {
                "id": 54708,
                "name": "八角街道",
                "pid": 2806,
                "children": []
              }
            ]
          }
        ]
      },
      {
        "id": 4,
        "name": "重庆",
        "pid": 4744,
        "children": [
          {
            "id": 48131,
            "name": "璧山区",
            "pid": 4,
            "children": [
              {
                "id": 58515,
                "name": "璧城街道",
                "pid": 48131,
                "children": []
              },
              {
                "id": 58516,
                "name": "璧泉街道",
                "pid": 48131,
                "children": []
              },
              {
                "id": 48192,
                "name": "八塘镇",
                "pid": 48131,
                "children": []
              }
            ]
          },
          {
            "id": 48202,
            "name": "巴南区",
            "pid": 4,
            "children": [
              {
                "id": 52490,
                "name": "城区",
                "pid": 48202,
                "children": []
              },
              {
                "id": 48372,
                "name": "石龙镇",
                "pid": 48202,
                "children": []
              },
              {
                "id": 48371,
                "name": "石滩镇",
                "pid": 48202,
                "children": []
              }
            ]
          },
          {
            "id": 48203,
            "name": "北碚区",
            "pid": 4,
            "children": [
              {
                "id": 54800,
                "name": "北温泉街道",
                "pid": 48203,
                "children": []
              },
              {
                "id": 54799,
                "name": "朝阳街道",
                "pid": 48203,
                "children": []
              },
              {
                "id": 48246,
                "name": "澄江镇",
                "pid": 48203,
                "children": []
              }
            ]
          }
        ]
      },
      {
        "id": 16,
        "name": "福建",
        "pid": 4744,
        "children": [
          {
            "id": 1303,
            "name": "福州市",
            "pid": 16,
            "children": [
              {
                "id": 1305,
                "name": "长乐区",
                "pid": 1303,
                "children": [
                  {
                    "id": 53259,
                    "name": "城区",
                    "pid": 1305,
                    "children": []
                  },
                  {
                    "id": 48927,
                    "name": "古槐镇",
                    "pid": 1305,
                    "children": []
                  },
                  {
                    "id": 59088,
                    "name": "航城街道",
                    "pid": 1305,
                    "children": []
                  }
                ]
              },
              {
                "id": 48713,
                "name": "仓山区",
                "pid": 1303,
                "children": [
                  {
                    "id": 48747,
                    "name": "城门镇",
                    "pid": 48713,
                    "children": []
                  },
                  {
                    "id": 51478,
                    "name": "城区",
                    "pid": 48713,
                    "children": []
                  },
                  {
                    "id": 59132,
                    "name": "仓前街道",
                    "pid": 48713,
                    "children": []
                  }
                ]
              },
              {
                "id": 48715,
                "name": "福清市",
                "pid": 1303,
                "children": [
                  {
                    "id": 48902,
                    "name": "城头镇",
                    "pid": 48715,
                    "children": []
                  },
                  {
                    "id": 51480,
                    "name": "城区",
                    "pid": 48715,
                    "children": []
                  },
                  {
                    "id": 48910,
                    "name": "东瀚镇",
                    "pid": 48715,
                    "children": []
                  }
                ]
              }
            ]
          },
          {
            "id": 1362,
            "name": "龙岩市",
            "pid": 16,
            "children": [
              {
                "id": 1365,
                "name": "长汀县",
                "pid": 1362,
                "children": [
                  {
                    "id": 44995,
                    "name": "城区",
                    "pid": 1365,
                    "children": []
                  },
                  {
                    "id": 45007,
                    "name": "策武镇",
                    "pid": 1365,
                    "children": []
                  },
                  {
                    "id": 44997,
                    "name": "大同镇",
                    "pid": 1365,
                    "children": []
                  }
                ]
              },
              {
                "id": 1369,
                "name": "连城县",
                "pid": 1362,
                "children": [
                  {
                    "id": 45128,
                    "name": "北团镇",
                    "pid": 1369,
                    "children": []
                  },
                  {
                    "id": 45126,
                    "name": "城区",
                    "pid": 1369,
                    "children": []
                  },
                  {
                    "id": 45137,
                    "name": "隔川乡",
                    "pid": 1369,
                    "children": []
                  }
                ]
              },
              {
                "id": 1368,
                "name": "上杭县",
                "pid": 1362,
                "children": [
                  {
                    "id": 45065,
                    "name": "白砂镇",
                    "pid": 1368,
                    "children": []
                  },
                  {
                    "id": 45078,
                    "name": "步云乡",
                    "pid": 1368,
                    "children": []
                  },
                  {
                    "id": 45075,
                    "name": "茶地镇",
                    "pid": 1368,
                    "children": []
                  }
                ]
              }
            ]
          },
          {
            "id": 1370,
            "name": "宁德市",
            "pid": 16,
            "children": [
              {
                "id": 1377,
                "name": "屏南县",
                "pid": 1370,
                "children": [
                  {
                    "id": 46200,
                    "name": "屏城乡",
                    "pid": 1377,
                    "children": []
                  },
                  {
                    "id": 46199,
                    "name": "长桥镇",
                    "pid": 1377,
                    "children": []
                  },
                  {
                    "id": 46195,
                    "name": "城区",
                    "pid": 1377,
                    "children": []
                  }
                ]
              },
              {
                "id": 1373,
                "name": "福鼎市",
                "pid": 1370,
                "children": [
                  {
                    "id": 46275,
                    "name": "白琳镇",
                    "pid": 1373,
                    "children": []
                  },
                  {
                    "id": 46274,
                    "name": "磻溪镇",
                    "pid": 1373,
                    "children": []
                  },
                  {
                    "id": 51502,
                    "name": "城区",
                    "pid": 1373,
                    "children": []
                  }
                ]
              },
              {
                "id": 1372,
                "name": "福安市",
                "pid": 1370,
                "children": [
                  {
                    "id": 46258,
                    "name": "坂中畲族乡",
                    "pid": 1372,
                    "children": []
                  },
                  {
                    "id": 55509,
                    "name": "城北街道",
                    "pid": 1372,
                    "children": []
                  },
                  {
                    "id": 55508,
                    "name": "城南街道",
                    "pid": 1372,
                    "children": []
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
]

核心代码主要是 findChildren 函数的实现。

posted @ 2022-06-26 16:55  暗恋桃埖源  阅读(408)  评论(0编辑  收藏  举报