从对象数组创建树层次结构

时间:2018-08-20 21:10:47

标签: javascript arrays object tree

首先,我只想提及我确实试图找到解决问题的方法,但是找不到适合我的方法。问题是,我有这样的数组:

const arr = [
  {
    leafName: 'name1',
    nodes: [1,2,3,4]
  },
  {
    leafName: 'name2',
    nodes: [1,2,3,4]
  },
  {
    leafName: 'name3',
    nodes: [1,2,4,5]
  },
  {
    leafName: 'name4',
    nodes: [6]
  }
];

我希望是这样的:

const expectedTree = {
  name: 'some root name',
  children: [
    {
      name: 1,
      children: [
        {
          name: 2,
          children: [
            {
              name: 3,
              children: [
                {
                  name: 4,
                  children: [
                    {
                      name: 'name1'
                    },
                    {
                      name: 'name2'
                    }
                  ]
                }
              ]
            },
            {
              name: 4,
              children: [
                {
                  name: 5,
                  children: [
                    {
                      name: 'name3'
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    },
    {
      name: 6,
      children: [
        {
          name: 'name4'
        }
      ]
    }
  ]
};

您可以看到leafName应该是树枝中的最后一个节点。同样,如果根节点与某个其他节点之间存在部分匹配,则应从最后匹配的节点添加新的子节点。例如,让我们将arr[1].nodesarr[2].nodes的前两个成员匹配,这意味着它们应该位于同一分支中,而arr[2].nodes的4和5分别拆分为单独的分支(作为{{ 1}})。我真的希望您能理解,也希望有人能帮助我。因为我已经坚持了两天,所以我自己也找不到解决方案。

任何评论将不胜感激。 ;)

1 个答案:

答案 0 :(得分:2)

您可以循环查看数组和节点,并通过为每个级别查看相同的名称来减少节点。如果一个节点不存在,请创建一个新节点并返回该节点的子节点。

var array = [{ leafName: 'name1', nodes: [1, 2, 3, 4] }, { leafName: 'name2', nodes: [1, 2, 3, 4] }, { leafName: 'name3', nodes: [1, 2, 4, 5] }, { leafName: 'name4', nodes: [6] }],
    result = [];

array.forEach(({ leafName, nodes }) => {
    nodes
        .reduce((level, name) => {
            var temp = level.find(o => o.name === name);
            if (!temp) {
                level.push(temp = { name });
            }
            return temp.children = temp.children || [];
        }, result)
        .push({ name: leafName });
});

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