【问题标题】:Recursion in hierarchical tree层次树中的递归
【发布时间】:2016-03-10 16:20:36
【问题描述】:

我想在 javascript 中遍历一个层次树以确定它有多少层。这是我的树的一个简短的 sn-p:

parent: [
   { id: 1 }
   {
       child1: [
           { id: 2 }
           {
               child2: [
                   { id: 3 }
                   {}
               ]
           }
       ],
       child3: [
           { id: 4 }
           { 
               child4: [
                   { id: 5 }
                   {}
               ],
               child5: [
                   { id: 6 }
                   {
                       child6: [
                           { id: 7 }
                           {}
                       ]
                   }
               ]
           }
       ]
   }
]

会有未知数量的父母和孩子。有 1 个确定性:

  • 每个元素(例如父元素)的数组中总是有 2 个对象。 第一个对象始终是一个 ID。 第二个对象包含它拥有的孩子。这可能为空或已填充

我的目标是确定树的级别数。例如,此示例树中有 4 个级别(parent = 1,child1 + child3 在同一级别 (2),child4 和 child5 在同一级别 (3),child6 = 4)。

这是我目前的代码:

for (var j in dependencyTree) {
    if (getObjectSize(dependencyTree[j][1]) > 0) {
        levelsArray.push(j + ': ' + recursiveFunction(dependencyTree[j][1], 1));
    }
}


function recursiveFunction(obj, lvls) {
    if (getObjectSize(obj) > 0) {
        for (var i in obj) {
            recursiveFunction(obj[i][1], lvls++);
        }
    }
    return lvls;
}

getObjectSize() 只返回对象的大小。 IE。它有多少直子。例如,对象 parent 将返回 2(child1child3)。

一开始,顶层parent 子级被传递到函数中。

我认为我的问题是 for 循环 (for (var i in obj)) 因为这可能会抓住第一个孩子 parent 拥有 (child1) 并最终返回 child1 拥有的级别数,即使 @ 987654333@还有更多。

任何帮助表示赞赏。

(尚未尝试 lodash,但被告知它不提供递归帮助)

编辑

{
    "Mobile": [
        {
            "id": 89
        },
        { 
            "Mobile Client": [
                {
                    "id": 100 
                },
                {}
            ]
        }
    ],
    "Service Platform": [
        {
            "id": 90
        },
        {
            "Service Platform": [
                {..."

编辑(新建议格式)

我和同事谈过了,新提议的数据格式是:

[
    {
        "name": "Mobile",
        "id": 89,
        "children": [
            {
                "name": "Mobile Client",
                "id": 100,
                "children": {}
            }
        ]
    }
];

这似乎是更可行的数据,将在明天实施

【问题讨论】:

  • 您可以控制数据的格式吗?看起来数据的编码方式很奇怪,具体来说,有些数组应该是对象,而对象应该是数组。
  • @Daniel 我正在与通过 REST 调用提供数据的人交谈,他说可以操纵它。您认为如何更好地格式化?
  • 我将从使用有效的 JSON 开始。这意味着您拥有的任何对象都应该被命名,否则您使用类似数组的方式遍历对象

标签: javascript recursion tree hierarchy


【解决方案1】:

尽管格式不同,但此解决方案会遍历数组和对象中的所有元素并对它们进行计数。

function count(array) {
    var c = 0;
    array.forEach(function (a) {
        c++;
        if (typeof a === 'object') {
            Object.keys(a).forEach(function (k) {
                if (Array.isArray(a[k])) {
                    c += count(a[k]);
                }
            });
        }
    });
    return c;
}

var parent = [{ id: 1 }, { child1: [{ id: 2 }, { child2: [{ id: 3 }, {}, ] }], child3: [{ id: 4 }, { child4: [{ id: 5 }, {}], child5: [{ id: 6 }, { child6: [{ id: 7 }, {}] }] }] }],
    newFormat = [{ "name": "Mobile", "id": 89, "children": [{ "name": "Mobile Client", "id": 100, "children": {} }] }];

document.write('<pre>' + JSON.stringify(count(parent), 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(parent, 0, 4) + '</pre><hr>');
document.write('<pre>' + JSON.stringify(count(newFormat), 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(newFormat, 0, 4) + '</pre>');

【讨论】:

    【解决方案2】:

    这里有一些示例代码可以让您了解如何遍历数据 - 信息通过控制台可见。

    var a = [
       { id: 1 },
       {
       child1: [
           { id: 2 },
           {
               child2: [
                   { id: 3 },
                   {}
               ]
           }
       ],
       child3: [
           { id: 4 },
           { 
               child4: [
                   { id: 5 },
                   {}
               ],
               child5: [
                   { id: 6 },
                   {
                       child6: [
                           { id: 7 },
                           {}
                       ]
                   }
               ]
           }
       ]
       }
    ];
    
    var getNumChildren=function(obj){
      var a = 0;
      if(obj[1]){
    for (var key in obj[1]) {
      a++;
      var res = getNumChildren(obj[1][key]);
      console.log(res,a);
      a += res;
    }
      }
      return a;
    }
    
    
    console.log(getNumChildren(a));

    就格式化数据而言,这种格式可能更有意义,更易于理解和使用

    [
      {"id":1,
        "children":[
          {"id":2,"children":[
            {"id":4,"children":[]},
            {"id":5,"children":[]}
          ]},
          {"id":3,"children":[]}
        ]
      }
    ]
    

    编辑

    如果您更新数据格式,您可以使用此代码。

    var data =[
      {"id":1,
        "children":[
          {"id":2,"children":[
            {"id":4,"children":[]},
            {"id":5,"children":[]}
          ]},
          {"id":3,"children":[]}
        ]
      },
      {"id":6,"children":[]}
    ]
    
    var getNumChildren=function(ca){
      var n = ca.length;
      ca.map(function(c){n += getNumChildren(c.children);})
      return n
    }
    
    document.write("result: " + getNumChildren(data));

    【讨论】:

    • 数据的格式将被编辑。检查我上面的编辑是否清楚。感谢您的帮助!
    猜你喜欢
    • 2023-03-24
    • 1970-01-01
    • 2019-12-16
    • 1970-01-01
    • 2021-09-07
    • 1970-01-01
    • 1970-01-01
    • 2018-02-21
    • 1970-01-01
    相关资源
    最近更新 更多