Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript:通过遍历从JSON对象获取引用_Javascript_Object_Traversal - Fatal编程技术网

Javascript:通过遍历从JSON对象获取引用

Javascript:通过遍历从JSON对象获取引用,javascript,object,traversal,Javascript,Object,Traversal,我需要从JSON对象获取引用,代码如下: var Tree = { data: { 0: { pk: 1, }, 1: { pk: 2, }, 2: { pk: 3, children: { 0: { pk: 11,

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

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 (i in data) { // console.log(data[i]); if(data[i].pk && data[i].pk == pk) return data[i]; if (typeof(data[i].children) == 'object') this.traverse(data[i].children, pk); }; }, } 变量树={ 数据:{ 0: { 主键:1,, }, 1: { 主键:2, }, 2: { 主键:3, 儿童:{ 0: { 主键:11, }, 1: { 主键:22, }, 2: { 主键:33, }, }, }, }, 遍历:函数(数据,主键){ 对于(数据中的i){ //console.log(数据[i]); if(数据[i].pk&&data[i].pk==pk) 返回数据[i]; if(typeof(data[i].children)='object') this.travel(数据[i].子对象,pk); }; }, } 当遍历顶级项时,代码工作得非常好:

>>> Tree.traverse(Tree.data, 1); Object {pk=1} >>>Tree.travel(Tree.data,1); 对象{pk=1} 但在获取子元素时会断开:

>>> Tree.traverse(Tree.data, 22); undefined >>>Tree.travel(Tree.data,22); 未定义 我很奇怪为什么会出现这种行为,当您取消对“//console.log(data[I]);”的注释时行,您将看到对象已获取但未返回


有什么想法吗?

你没有在
这个之前加上
return


编辑:

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);

选中live here:

这是一个很长的过程,但您正在为
循环创建一个全局变量。请改为尝试(数据中的var i)
,然后报告

如果这不是整个对象,并且在父
对象
文本中有一个键(如
3:…
)的属性在
子属性中不存在,它显然会返回
未定义的
,因为该键没有此类属性

编辑:根据您的评论,这可能也是函数范围的问题,因为您正在使用尾部递归来迭代具有多个层的对象。 因此,尝试将当前对象引用置于函数范围之外,就像在任何需要动态引用的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
,并且将包含匹配的对象或子对象。

您能给我完整的示例代码吗?我试过了,但没有起作用。@K,我编辑了它,检查了更改,它有一条注释来澄清问题。我尝试了
(数据中的var I)
,但不起作用,它仍然响应
未定义的
。第二部分:我认为这里的数据是一个参考(与C语言中的point相同)。当
this.transverse(数据[i].子对象,pk)时它指向树的第二层。但仍然感谢您的回复。非常感谢,今天早上我有一个非常相同的想法,但还没有尝试。:-)不用担心,很高兴能帮上忙。:-)