Algo找到深度并按顺序插入JSON数组

时间:2013-12-11 14:36:06

标签: javascript json algorithm node.js tree

我需要从基于parentId的json数组中找到关系,并在顺序结构中插入到数组中。 ParentId映射到_Id,即父。

[{"_Id":1,parentId:"",name:'A'},
{"_Id":4,parentId:2,name:'D'},
{"_Id":2,parentId:1,name:'B'},
{"_Id":5,parentId:3,name:'E'},
{"_Id":3,parentId:1,name:'C'}]

上述数组需要使用深度字段转换为以下结构。

[{"_Id":1,parentId:"",name:'A', 'depth':1},   
{"_Id":2,parentId:1,name:'B', 'depth':2},
{"_Id":4,parentId:2,name:'D', 'depth':3},
{"_Id":3,parentId:1,name:'C', 'depth':2},
{"_Id":5,parentId:3,name:'E', 'depth':3}]

1
    2
        4
    3   
        5

我是一名新手程序员,需要提示。

  var finalArray = [];
 var initPath = function (task) {
     // TODO
 };
 for (var i = 0, len = array.length; i < len; i++) {
     if (array[i].parentId == "") {
         array[i]['depth'] = 1;
         finalArray(array[i]);
         initPath(array[i]);
     }
 }

3 个答案:

答案 0 :(得分:1)

嗯,你可以很容易地找到根目录:它们没有parentId。获得根后,可以找到所有深度为2的节点:父节点为根节点的任何节点。更进一步:如果节点的父节点位于深度n-1(根是特殊情况),则节点位于深度n处。继续观察,直到所有内容都分配给它。

答案 1 :(得分:1)

以下方法将递归遍历树,并在每次下降到另一个级别时向计数添加1。这真的不是最有效的方式,但在我看来这是最简单的方法。

var array = [{"_Id":1,parentId:"",name:'A'},
{"_Id":4,parentId:2,name:'D'},
{"_Id":2,parentId:1,name:'B'},
{"_Id":5,parentId:3,name:'E'},
{"_Id":3,parentId:1,name:'C'}];

for(var i=0;i<array.length;i++) {
  array[i]["depth"] = findDepth(array[i]);   
}

function findDepth(item) {
    if(item.parentId==="")
        return 1;
    for(var i=0;i<array.length;i++) {
        if(array[i]._Id===item.parentId)
            return 1+findDepth(array[i]);
    }
}

答案 2 :(得分:1)

嗯,我不会为你完成所有工作,但这里有一个解决方案,可以在不重新排列元素顺序的情况下添加深度。它是 on JSFiddle ,这是相关代码:

var addDepth = function(data) {
    var depth = 0, nodes = data.filter(function(item) {
        return item.parentId == "";
    }), total = nodes.length;

    do {
        depth++;
        nodes.forEach(function(node) {node.depth = depth;});
        var ids = nodes.map(function(item) {return item["_Id"];});
        nodes = data.filter(function(item) {
            return ids.indexOf(item.parentId) > -1;
        });
        total += nodes.length
    } while (nodes.length > 0 && total <= data.length);
    return data;
};

请注意,这会更改阵列,并且不会创建克隆。那可能是也可能不是你想要的。 (因为我最近专注于函数式编程,它至少会略微冒犯我自己的敏感性。)这应该相对容易改变。

请注意,这实际上是我的第二个版本。 first one 在我看来更优雅。但它基于 the Ramda library 我还在开发中。虽然我喜欢这个库,并且发现它易于使用,但对于那些没有进行大量函数式编程的人来说,我不一定希望这些代码更加明显:

var addDepth = function(data) {
    var depth = 0, nodes = filter(pipe(get("parentId"), eq("")), data), 
        total = nodes.length;
    do {
        depth++;
        nodes.forEach(function(node) {node.depth = depth;});
        nodes = filter(pipe(get("parentId"), flip(contains)(pluck("_Id", nodes))), data);
        total += nodes.length
    } while (nodes.length > 0 && total <= data.length);
    return data;
};