Javascript对象层次结构简化

Javascript Object Hierarchy Simplification

本文关键字:层次结构 对象 Javascript      更新时间:2023-09-26

我有一个类似于以下的平面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>

这很好,但似乎我需要一些递归的理解或更快的方法来做…

这是我的小提琴

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

算法如下:

  • 对于索引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示例。

注意,该算法假设它是一个,并且输入参数是有效的。它不检查循环,也不检查是否存在具有此类id的父节点。如果需要,您可以实现它。