从包含子字段的平面列表构造层次结构树?

时间:2014-12-03 08:47:39

标签: javascript arrays tree hierarchy

我有一个"页面"的列表带有子字段的对象。此子字段引用列表中的另一个对象。我想基于此字段从此列表中创建树层次结构。 我找到了一个解决方案here,但只有当我有一个父字段时它才有效。这就是我的原始列表:

[
  {
  id: 1,
  title: 'home',
  child: null
  },
  {
  id: 2,
  title: 'about',
  child: null
  },
  {
  id: 3,
  title: 'team',
  child: 4
  },
  {
  id: 4,
  title: 'company',
  child: 2
  }
]

我想把它转换成这样的树结构:

[
 {
  id: 1,
  title: 'home',
  },
  {
   id: 3,
   title: 'team',
   children:  [
   {
    id: 4,
    title: 'company',
    children: {
      id: 2,
      title: 'about',
    }
  }
]
]

我希望有一个可重用的函数,我可以随时调用任意列表。有人知道处理这个问题的好方法吗?任何帮助或建议将不胜感激!

2 个答案:

答案 0 :(得分:1)

使用Underscore.js添加父项,然后使用this solution

找到解决方案
_.each(flat, function (o) {
  o.child.forEach(function (childId) {
    _.findWhere(flat, {id: childId}).parent = o.id;
  });
});

答案 1 :(得分:0)

下面的函数从对象列表构建树。 它对任何格式都不紧张。 与您的示例唯一的区别是您提供的是parent密钥,而不是child

function buildTree(flatList, idFieldName, parentKeyFieldName, fieldNameForChildren) {
    var rootElements = [];
    var lookup = {};

    flatList.forEach(function (flatItem) {
      var itemId = flatItem[idFieldName];
      lookup[itemId] = flatItem;
      flatItem[fieldNameForChildren] = [];
    });

    flatList.forEach(function (flatItem) {
      var parentKey = flatItem[parentKeyFieldName];
      if (parentKey != null) {
        var parentObject = lookup[flatItem[parentKeyFieldName]];
        if(parentObject){
          parentObject[fieldNameForChildren].push(flatItem);
        }else{
          rootElements.push(flatItem);
        }
      } else {
        rootElements.push(flatItem);
      }

    });

    return rootElements;
  }

Here is a fiddle使用您的示例作为输入。

原始来源comes from this answer