【问题标题】:Javascript: Get a reference from JSON object with traverseJavascript:通过遍历从 JSON 对象获取引用
【发布时间】:2010-09-05 10:03:50
【问题描述】:

我需要从 JSON 对象中获取引用,代码如下:

变种树 = { 数据: { 0:{ PK:1, }, 1:{ PK:2, }, 2:{ PK:3, 孩子们: { 0:{ PK:11, }, 1:{ PK:22, }, 2:{ PK:33, }, }, }, }, 遍历:函数(数据,pk){ 对于(我在数据中){ // console.log(data[i]); 如果(数据[i].pk && 数据[i].pk == pk) 返回数据[i]; if (typeof(data[i].children) == 'object') this.traverse(data[i].children, pk); }; }, }

代码在遍历顶层项目时效果很好:

>>> Tree.traverse(Tree.data, 1); 对象 {pk=1}

但是在获取子元素的时候就坏了:

>>> Tree.traverse(Tree.data, 22); 不明确的

当您取消注释“//console.log(data[i]);”时,我很奇怪为什么会出现这种行为行,您将看到对象已获取但未返回。

有什么想法吗?

【问题讨论】:

    标签: javascript object traversal


    【解决方案1】:

    你没有把return放在this.traverse(data[i].children, pk);之前。


    编辑:

    var Tree = {
        data: {
            0: {
                pk: 1,
            },
            1: {
                pk: 2,
            },
            2: {
                pk: 3,
                children: {
                    0: {
                        pk: 11,
                    },
                    1: {
                        pk: 22,
                    },
                    2: {
                        pk: 33,
                    },
                },
            },
        },
    
        traverse: function(data, pk) {
            for (var i in data) {
                // console.log(data[i]);
                if(data[i].pk && data[i].pk == pk)
                    return data[i];
    
                if (typeof(data[i].children) == 'object') {
                    var retVal = this.traverse(data[i].children, pk);
                    if (typeof retVal!='undefined') {//here was the logical problem,there might be more than one
                                                     //object, we can't return the result of traversing first one.
                                                     //So we will check, if no return, we go on searching
                        return retVal;
                    }
                }
    
            };
        },
    };
    
    alert(Tree.traverse(Tree.data, 1).pk);
    alert(Tree.traverse(Tree.data, 22).pk);
    

    在这里查看直播:http://jsfiddle.net/rq4LK/

    【讨论】:

    • 你能给我完整的示例代码吗?我试过了,但没有生效。
    • @K K,我编辑了它,检查更改,它有一个评论来澄清问题。
    【解决方案2】:

    这是一个长镜头,但您正在 for 循环中创建一个全局变量。请改用for(var i in data),然后再报告。

    如果这不是整个对象,并且您在父 Object 文字中有一个带有键的属性(如 3: ...),而该属性在 children 子属性中不存在,它显然会返回 @987654326 @,因为该键没有这样的属性。

    编辑:根据您的评论,这也可能是函数范围的问题,因为您使用 尾递归 来迭代具有多个层的对象。 因此,尝试将当前对象引用放在函数范围之外,就像在任何需要动态引用的 javascript 语言构造中所做的那样:

    var current = null , match = null ;
    
    function traverse() {
    
        var data = arguments[0] ;
        var pk = arguments[1] ;
    
            for(var i in data) {
    
                    current = data[i] ; /* DEBUG */console.log( current.toSource() ) ; //!! Object.prototype.toSource() requires a W3 compatible browser (like FF)
    
                    if(current.pk !== undefined && current.pk === pk) return current ;
                    else if( typeof current.children === "object") traverse(current.children, pk);
    
             }
    }
    
    match = traverse(data,pk) ;
    

    编辑 2: 我的逻辑有缺陷。试试这个:

    var match = null ;
    
    function traverse() {
    
        var data = arguments[0] ;
        var pk = arguments[1] ;
    
        var current = null ;
    
            for(var i in data) {
    
                    current = data[i] ; /* DEBUG */console.log( current.toSource() ) ; //!! Object.prototype.toSource() requires a W3 compatible browser (like FF)
    
                    if(current.pk !== undefined && current.pk === pk) match = current ; //!! if there is a match set the variable match to the current object
                    else if( typeof current.children === "object") traverse(current.children, pk); //!! else use recursion to test a child property if present
    
             }
    
    }
    

    使用它,如果您的对象包含指定的属性 match 将不是 null 并且将包含匹配的对象或子对象。

    【讨论】:

    • 我尝试了 for (var i in data) 但不起作用,它仍然响应 undefined。对于您的第二部分:我认为数据是这里的参考(与 C 语言中的点相同)。当 this.traverse(data[i].children, pk); 它指向树的第 2 层。但是仍然感谢您的回复。
    • 非常感谢,今天早上我有一个最相同的想法,但还没有尝试过。 :-)
    • 不用担心,很高兴能够提供帮助。 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-10
    • 2017-12-28
    • 2017-07-10
    • 2023-03-24
    • 2015-09-16
    • 2017-12-28
    • 1970-01-01
    相关资源
    最近更新 更多