查找给定json树中任何节点/参数对象的级别,如结构变量计数器 [英] Finding level of any node/parameter object in given json tree like structure variable counter

查看:59
本文介绍了查找给定json树中任何节点/参数对象的级别,如结构变量计数器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的json结构就像一个树结构。父节点可以有任意数量的子节点。

非叶/父节点在JSON对象的svalue属性中有子节点。叶节点具有键executionValueList。因此,通过这种方式使用这些键,我们可以区分叶节点和父节点。



在我的JSON中,我有两个节点P1,P2在0级.P1没有孩子。 P2有两个孩子P21和P22。 P21没有任何孩子。 P22有两个孩子P221和P222。 P221没有子节点并且是叶节点。 P222有两个孩子P2221和P2222。 P2221和P2222没有子节点并且是叶节点。



节点P1,P2的等级为0.

对于P21和P22,等级为1.

对于P221和P222,等级为2.

对于P2221和P2222,等级为3.



那么如何找到等级我的JSON中的任何节点/参数对象?在javascript中编写函数以查找给定变量计数器中任何节点/参数的级别。我的脚本是这样的:

我试过这个,但是它没有给出正确的结果



My json structure is like a tree structure.A parent node can have any number of children node.
A non-leaf/parent node has children in svalue attribute of JSON object. A leaf node has the key "executionValueList". So In this way using these keys,we can differentiate between leaf nodes and parent nodes.

In my JSON ,i have two nodes P1,P2 at level 0. P1 does not have any child. P2 has two children P21 and P22. P21 does not have any child. P22 has two child P221 and P222. P221 has no child and is leaf node. P222 has two child P2221 and P2222. P2221 and P2222 have no child and are leaf nodes.

Level of node P1,P2 is 0.
For P21 and P22,level is 1.
For P221 and P222,the level is 2.
For P2221 and P2222,the level is 3.

So how to find the level of any node/parameter object in my JSON? Write a function in javascript to find level of any node/parameter in the given variable counter. My script is like this:
I tried this but it doesn't give correct results all the time

<html>

<head>

    <script type="text/javascript">
        var counter = {
            "executionNameList": ["exe1", "exe2"],
            "algoList": [{
                "name": "Algorithm1",
                "paramList": [{
                    "name": "P1",
                    "executionValueList": [{
                        "name": "exe1",
                        "value": "v1"
                    }, {
                        "name": "exe2",
                        "value": "v2"
                    }]
                }, {
                    "name": "P2",
                    "svalue": [{
                        "name": "P21",
                        "executionValueList": [{
                            "name": "exe1",
                            "value": "v3"
                        }, {
                            "name": "exe2",
                            "value": "v4"
                        }]
                    }, {
                        "name": "P22",
                        "svalue": [{
                            "name": "P221",
                            "executionValueList": [{
                                "name": "exe1",
                                "value": "v5"
                            }, {
                                "name": "exe2",
                                "value": "v6"
                            }]
                        }, {
                            "name": "P222",
                            "svalue": [{
                                    "name": "P2221",
                                    "executionValueList": [{
                                        "name": "exe1",
                                        "value": "v7"
                                    }, {
                                        "name": "exe2",
                                        "value": "v8"
                                    }]
                                }, {
                                    "name": "P2222",
                                    "executionValueList": [{
                                        "name": "exe1",
                                        "value": "v9"
                                    }, {
                                        "name": "exe2",
                                        "value": "v10"
                                    }]
                                }

                            ]
                        }]
                    }]
                }]
            }, {
                "name": "Algorithm2",
                "paramList": [{
                    "name": "P3",
                    "executionValueList": [{
                        "name": "exe1",
                        "value": "v11"
                    }, {
                        "name": "exe2",
                        "value": "v12"
                    }]
                }, {
                    "name": "P4",
                    "svalue": [{
                        "name": "P41",
                        "executionValueList": [{
                            "name": "exe1",
                            "value": "v13"
                        }, {
                            "name": "exe2",
                            "value": "v14"
                        }]
                    }, {
                        "name": "P42",
                        "svalue": [{
                            "name": "P421",
                            "executionValueList": [{
                                "name": "exe1",
                                "value": "v15"
                            }, {
                                "name": "exe2",
                                "value": "v16"
                            }]
                        }, {
                            "name": "P422",
                            "executionValueList": [{
                                    "name": "exe1",
                                    "value": "v17"
                                }, {
                                    "name": "exe2",
                                    "value": "v18"
                                }

                            ]
                        }]
                    }]
                }]
            }]
        };




        function parameterColumnsCounter(counter) {
            var temp = {};
            var max = 0;
            var k = 0;
            for (var i = 0; i < Object.keys(counter.algoList).length; i++) {
                for (var j = 0; j < Object.keys(counter.algoList[i].paramList).length; j++) {
                    temp[k] = getDepth(counter.algoList[i].paramList[j]);
                    k++;
                }
            }

            max = temp[0];
            for (x = 0; x < Object.keys(temp).length; x++) {
                if (temp[x] > max) {
                    max = temp[x];
                }
            }

            return max
        }

        function getDepth(obj) {
            var depth = 0;
            if (obj.svalue) {
                obj.svalue.forEach(function(d) {
                    var tmpDepth = getDepth(d)
                    if (tmpDepth > depth) {
                        depth = tmpDepth
                    }
                })
            }
            return 1 + depth
        }

        function getLevel(parameter) {
            var a = getDepth(parameter);
            var b = parameterColumnsCounter(counter);
            return b - a;
        }



        alert(getLevel(counter.algoList[0].paramList[1].svalue[1])); // for P21 level returned is 1 but there is something wrong with my logic i guess
    </script>
</head>

<body>


</body>

</html>

推荐答案

您的代码当然应该看起来更简单。 (对不起,我不想花这么多时间来检查或调试它。)



这是个主意。创建一个递归使用的函数。重要的一点是:您应该将当前节点级别传递给它。它应该是这样的:

Your code certainly should look simpler. (Sorry, I don't want spend so much time on reviewing or debugging it.)

Here is the idea. Create one function to be used recursively. Important point is: you should pass current node level to it. It should be something like this:
function addNodeLevels(parent, currentLevel) {
   if (!parent) return; // important!
   if (typeof parent != typeof {}) return; // important!
   parent.level = currentLevel;
   for (var index in parent)
      // child object is parent[index]:
      addNodeLevel(parent[index], currentLevel + 1);
}



这有两个问题。首先,对于一般对象,这可能导致无限递归。因此,它只能在某些情况下安全使用; JSON就是其中之一。您可以将JSON字符串解析为此类对象图,这将是使用此函数的有效目标;用这种方式解析: JSON.parse() - JavaScript | MDN [ ^ ]。



因此,您解析JSON,获取解析器返回的对象,并将其传递给此函数, currentLevel 为零。就是这样。



第二个问题更严重。如果某些对象已经具有属性级别,该怎么办?比这个算法会严重破坏这些现有的属性。顺便说一下,您可以轻松检查属性: Object.prototype .hasOwnProperty() - JavaScript | MDN [ ^ ]。



那么,什么是更重但更通用的解决方案?你可以使用一些外部初始化的对象,我们称之为 nodeLevelMap 。换句话说,您可能希望在单独的map对象中存储JSON结构中JSON对象和每个级别的映射。方法如下:


There are two problems with that. First, for a general object, this can cause "infinite recursion". So, it can be safely used only in some cases; JSON is one of them. You can parse JSON string into such object graph which will be a valid target for the use of this function; parse it this way: JSON.parse() — JavaScript | MDN[^].

So, you parse JSON, get the object returned by parser, and pass it to this function, with currentLevel of zero. That's it.

The second problem is more serious. What if some of the objects already have the property level? Than this algorithm will disrupt these existing properties badly. By the way, you can easily check-up the property: Object.prototype.hasOwnProperty() — JavaScript | MDN[^].

So, what would be a heavier but more universal solution? You can use some externally initialized object, let's call it nodeLevelMap. In other words, you may want to store mapping between JSON objects and levels of each in your JSON structure in a separate "map" object. Here is how:

var nodeLevelMap = {};

// ...

function addNodeLevels(parent, currentLevel, nodeLevelMap) {
   if (!parent) return; // important!
   if (typeof parent != typeof {}) return; // important!
   nodeLevelMap[parent] = currentLevel;
   for (var index in parent)
      // child object is parent[index]:
      addNodeLevel(parent[index], currentLevel + 1, nodeLevelMap);
}

// ...

// hope you can complete the code:
// parse JSON, pass returned object
// to this function with nodeLevelMap = 0...



在顶层对象上调用此函数后,在O(1)的时间复杂度 nodeLevelMap 对象中,每个对象都可以检索所有级别。

< br $>




初始版本之后,我修复了代码中的一个错误,稍后对其进行了简化(替换为var child = ......评论。



现在,还有一项改进。重复执行的行中存在轻微的性能泄漏


After this function is called on the top object, all levels can be retrieved by each object from nodeLevelMap object at the time complexity of O(1).



After the initial version, I fixed a bug in the code and later simplified it a bit (replaced "var child = …" with comment).

Now, one more improvement. There is a minor performance leak in repeatedly executed line

if (typeof parent != typeof {}) return;



通过预先计算的类型字符串可以略微改善:


It could be slightly improved by having a pre-calculated type string:

var objectType = typeof {};

//... 

function addNodeLevels(parent, currentLevel, nodeLevelMap) {
   // ...
   if (typeof parent != objectType) return;
   // ...
}



通常,我为常量定义了一些全局对象,并在整个脚本中重用它们。



在地图上的操作和性能(O(1) ),另请参阅:

Big O表示法 - 维基百科,免费的百科全书 [ ^ ],

时间复杂性 - 维基百科,免费的百科全书 [ ^ ]。



[结束编辑]



基本上,就是这样。想法,评论,问题?



-SA


这篇关于查找给定json树中任何节点/参数对象的级别,如结构变量计数器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆