用 JavaScript 构建一棵树

问题描述

大家好,我有一个问题,我需要创建一个树数据结构,我无法平衡它,我在互联网上尝试了一些脚本,但找不到解决方案,有人可以帮助我吗?

我有一个对象数组。

const data = [
      {
        id: 1111,code: '1',name: 'Item 1',parent_code: '',children: []
      },{
        id: 11110,code: '12',name: 'Item 12',parent_code: '1',{
        id: 99999,code: '3',name: 'Item 33',{
        id: 99992,code: '114',name: 'Item 114',parent_code: '3',{
        id: 99993,code: '115',name: 'Item 115',parent_code: '114',];

我需要怎么离开

const expectedData = [
      {
        id: 1111,children: [
          {
            id: 11110,children: []
          },]
      },children: [
          {
            id: 99992,children: [
              {
                id: 99993,children: []
              },]
          },]

我需要添加代码和父代码,我尝试了一些并得到了这个结果,但它不是我想要的

    let parents = [];

    data.forEach(d => {
      if(!d.parent_code) {
        d.children = data.filter(dt => dt.parent_code === dt.code);

        parents.push(d);
      }
    });

    console.log(parents);

结果是

const result = [
      {
        id: 1111,]

上不去第三层,看parent_code 3

解决方法

你很接近:

data.forEach(d => {
  d.children = data.filter(dt => dt.parent_code === d.code);
  if(!d.parent_code) {
    parents.push(d);
  }
});

您想为所有元素找到子元素,而不仅仅是根元素。此外,您将 ddt 混为一谈,parentchild 会在 IMO 中更具可读性。


请注意,这是 O(n²),O(n) 的解决方案是创建一个从代码到对象的 Map,然后遍历对象一次,并将每个对象推送到父对象(可以在 O (1)从地图)。然后将对象本身添加到 Map。如果在迭代子级时父级不存在,则添加一个新对象作为父级。到达父级时合并。

,

您可以使用一个对象作为参考并在单个循环中构建树。

const
    data = [{ id: 1111,code: '1',name: 'Item 1',parent_code: '',children: [] },{ id: 11110,code: '12',name: 'Item 12',parent_code: '1',{ id: 99999,code: '3',name: 'Item 33',{ id: 99992,code: '114',name: 'Item 114',parent_code: '3',{ id: 99993,code: '115',name: 'Item 115',parent_code: '114',children: [] }],tree = function (data,root) {
        var t = {};
        data.forEach(o => {
            Object.assign(t[o.code] = t[o.code] || {},o);
            t[o.parent_code] = t[o.parent_code] || {};
            t[o.parent_code].children = t[o.parent_code].children || [];
            t[o.parent_code].children.push(t[o.code]);
        });
        return t[root].children;
    }(data,'');

console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }

,

O(n) 就地解决方案

let r=[],h= data.reduce((a,c)=> (a[c.code]=c,a),{});
data.forEach((c,i,a,e=h[c.parent_code]) => (e ? e.children : r).push(c) );

const data = [
      {
        id: 1111,children: []
      },{
        id: 11110,{
        id: 99999,{
        id: 99992,{
        id: 99993,];
    
let r=[],e=h[c.parent_code]) => (e ? e.children : r).push(c) );

console.log(r);