Javascript对象层次结构简化

时间:2015-11-06 03:32:42

标签: javascript json

我有一个与此类似的扁平JSON数组:

var flatObj = 
[
    { id : "1", parentid : "0", name : "obj 1" },
    { id : "2", parentid : "1", name : "obj 2" },
    { id : "3", parentid : "2", name : "obj 3" },
    { id : "4", parentid : "3", name : "obj 4" },
    { id : "5", parentid : "4", name : "obj 5" },
    { id : "6", parentid : "5", name : "obj 6" },
    { id : "7", parentid : "1", name : "obj 7" },
    { id : "8", parentid : "1", name : "obj 8" },
    { id : "9", parentid : "1", name : "obj 9" }
];

我希望通过传递一个id来显示这个层次结构,并通过一个简单的函数通过父ID获得基于该id的层次结构。不太确定是否重要,如果我已经知道它会有多深,但在我的情况下,我知道层次结构在5级深处停止。但是,我创建了一个函数来执行此操作,但它的代码很多?我想减肥它可能使用递归方法?这是我的功能。

function getItems(id){

    if(!id){
        document.getElementById("demo").innerHTML = "";
        id = document.getElementById("hvitems").value;
    }

    for(a=0;a<flatObj.length;a++){

        var object_a = flatObj[a];
        var object_id_a = object_a.id;

        if(object_id_a == id){

            var object_name_a = object_a.name;

            document.getElementById("demo").innerHTML += "(" + object_id_a + ") " + object_name_a + "<br>";

            // look for parentid's that match the id
            for(b=0;b<flatObj.length;b++){

                var object_b = flatObj[b];
                var object_id_b = object_b.id;
                var object_pid_b = object_b.parentid;

                if(object_pid_b == object_id_a){

                    var object_name_b = object_b.name;

                    document.getElementById("demo").innerHTML += " - (" + object_id_b + ") " + object_name_b + "<br>";

                    // look for parentid's that match the id
                    for(c=0;c<flatObj.length;c++){

                        var object_c = flatObj[c];
                        var object_id_c = object_c.id;
                        var object_pid_c = object_c.parentid;

                        if(object_pid_c == object_id_b){

                            var object_name_c = object_c.name;

                            document.getElementById("demo").innerHTML += " -- (" + object_id_c + ") " + object_name_c + "<br>";

                            // look for parentid's that match the id
                            for(d=0;d<flatObj.length;d++){

                                var object_d = flatObj[d];
                                var object_id_d = object_d.id;
                                var object_pid_d = object_d.parentid;

                                if(object_pid_d == object_id_c){

                                    var object_name_d = object_d.name;

                                    document.getElementById("demo").innerHTML += " --- (" + object_id_d + ") " + object_name_d + "<br>";

                                    // look for parentid's that match the id
                                    for(e=0;e<flatObj.length;e++){

                                        var object_e = flatObj[e];
                                        var object_id_e = object_e.id;
                                        var object_pid_e = object_e.parentid;

                                        if(object_pid_e == object_id_d){

                                            var object_name_e = object_e.name;

                                            document.getElementById("demo").innerHTML += " ---- (" + object_id_e + ") " + object_name_e + "<br>";

                                            // get all ids of the parentid

                                        }

                                    }

                                }

                            }

                        }

                    }

                }

            }

        }

    }

}

getItems(1);
// or getItems(3); ...

我通过div显示它:

<div id="demo"></div>

这很有效,但似乎我需要对递归或更快的方法有所了解......

这是我的fiddle

1 个答案:

答案 0 :(得分:1)

你不应该有N个嵌套循环。这就是为什么我们有recursion

算法将如下:

  • 索引id
    • 找到包含此id的项目并输出信息
    • 查找parentid等于id的所有项目,并使用id
    • 重复这些步骤

就这么简单:

function getItems(id, indent) { // for index `id`
    var current = flatObj.filter(function(x) { // find the item... 
        return (x.id == id); // ... with this id
    })[0];

    // and output information
    document.body.innerHTML += indent + " (" + current.id + ") " + current.name + "<br>"; 

    // find all items ...
    flatObj.forEach(function(x) {        
        if (x.parentid == id) { // ...with parentid equal to id
            getItems(x.id, indent + '-'); // and repeat these steps using their ids
        }
    });
}

getItems(id, '');

indent只是一个字符串,在开头是空的,并且在每次递归调用时都会增加一-,因此它看起来像你需要的那样。

这是工作JSFiddle example

请注意,此算法假设它是且输入参数有效。它不会检查循环,或是否存在具有此id的父节点。如果需要,您可以实施它。