【问题标题】:Javascript array sorting by level [duplicate]Javascript数组按级别排序[重复]
【发布时间】:2016-12-01 21:56:33
【问题描述】:

我在同一个数组中有一对多关系的数据。组织是按层级建立的。一个元素的父级总是比它自己高一级,并且被 parentId 引用。

如何从这个数组中得到一个多级数组?最高级别的元素将是主数组,其子元素在 javascript 中作为子数组?

[{
    _id: 100,
    level: 3,
    parentId: null,
},
{
    _id: 101,
    level: 2,
    parentId: 100,
},
{
    _id: 102,
    level: 2,
    parentId: 100,
},
{
    _id: 103,
    level: 2,
    parentId: 100,
},
{
    _id: 104,
    level: 1,
    parentId: 101,
},
{
    _id: 105,
    level: 1,
    parentId: 102,
},
{
    _id: 106,
    level: 1,
    parentId: 101,
},
{
    _id: 107,
    level: 1,
    parentId: 103,
},
{
    _id: 108,
    level: 1,
    parentId: 102,
},
{
    _id: 109,
    level: 1,
    parentId: 103,
}]

预期的输出是

                       100
                        |
       ------------------------------------
       |                |                 |
      101              102               103
    -------           ------            ------
    |     |           |    |            |    |
   104   106         105  108          107  109

谢谢

【问题讨论】:

  • 如果我理解您要求包含此类数据的首选|建议|最佳结构?如果是的话,首先我宁愿使用从父级到子级的从低到高的级别。
  • @MattBurland 我真的不知道从哪里开始,尝试获得最高级别然后从那里链接孩子,但我认为我错过了我需要创建新子数组的部分。如果这对你有意义,不要这样做
  • @cFreed 这就是寻找的输出,无法弄清楚实现。我应该编辑我的问题以使其更清楚。谢谢

标签: javascript arrays sorting


【解决方案1】:

使用Array#reduce根据节点的ID创建一个哈希,然后使用Array.forEach()迭代数组。如果父id为null,则为根,否则添加到父子的子节点:

function createTree(data) {
  var tree = [];
  
  data.forEach(function(node) {
    var parentId = node.parentId;
    
    if(parentId === null) {
      tree.push(node);
    } else {
      (this[parentId].children || (this[parentId].children = [])).push(node);
    }
  }, data.reduce(function(hash, node) {
    hash[node._id] = node;
    
    return hash;
  }, Object.create(null)));
  
  return tree;
}

var data = [{
    _id: 100,
    level: 3,
    parentId: null,
},
{
    _id: 101,
    level: 2,
    parentId: 100,
},
{
    _id: 102,
    level: 2,
    parentId: 100,
},
{
    _id: 103,
    level: 2,
    parentId: 100,
},
{
    _id: 104,
    level: 1,
    parentId: 101,
},
{
    _id: 105,
    level: 1,
    parentId: 102,
},
{
    _id: 106,
    level: 1,
    parentId: 101,
},
{
    _id: 107,
    level: 1,
    parentId: 103,
},
{
    _id: 108,
    level: 1,
    parentId: 102,
},
{
    _id: 109,
    level: 1,
    parentId: 103,
}];

var result = createTree(data);

console.log(result);

【讨论】:

  • 使用this[parentId].children || (this[parentId].children = []);而不是this[parentId].children = this[parentId].children || [];有什么特殊原因吗?
  • 是的。再看代码。
  • 谢谢,这是我需要的,去学习那些功能。
【解决方案2】:

您可以使用单个循环从数据中创建一棵树。此提议也适用于未排序的数据。

var data = [{ _id: 100, level: 3, parentId: null }, { _id: 101, level: 2, parentId: 100 }, { _id: 102, level: 2, parentId: 100 }, { _id: 103, level: 2, parentId: 100 }, { _id: 104, level: 1, parentId: 101 }, { _id: 105, level: 1, parentId: 102 }, { _id: 106, level: 1, parentId: 101 }, { _id: 107, level: 1, parentId: 103 }, { _id: 108, level: 1, parentId: 102 }, { _id: 109, level: 1, parentId: 103 }],
    tree = function (data, root) {
        var r, o = Object.create(null);
        data.forEach(function (a) {
            a.children = o[a._id] && o[a._id].children;
            o[a._id] = a;
            if (a.parentId === root) {
                r = a;
            } else {
                o[a.parentId] = o[a.parentId] || {};
                o[a.parentId].children = o[a.parentId].children || [];
                o[a.parentId].children.push(a);
            }
        });
        return r;
    }(data, null);

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-08
    • 1970-01-01
    • 2019-08-20
    • 2016-12-28
    • 1970-01-01
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多