递归问题;解析 JSON

Posted

技术标签:

【中文标题】递归问题;解析 JSON【英文标题】:trouble with recursion; parsing JSON 【发布时间】:2012-01-17 23:02:19 【问题描述】:

我有一个这样的 json 对象:

[
    "thing": "Top",
    "data": 
        "childs": [
            "thing": "a",
            "data": 
                "text": "sdfgdg1",
                "morestuff": 
                    "thing": "Top",
                    "data": 
                        "childs": [
                            "thing": "a",
                            "data": 
                                "text": "sdfg2",
                                "morestuff": "",
                            
                        ,
                        
                            "thing": "a",
                            "data": 
                                "text": "gfhjfghj3",
                                "morestuff": 
                                    "thing": "Top",
                                    "data": 
                                        "childs": [
                                            "thing": "a",
                                            "data": 
                                                "text": "asdfsadf 2 4",
                                                "morestuff": 
                                                    "thing": "Top",
                                                    "data": 
                                                        "childs": [
                                                            "thing": "a",
                                                            "data": 
                                                                "text": "asdfsadf 2 5",
                                                                "morestuff": 
                                                                    "thing": "Top",
                                                                    "data": 
                                                                        "childs": 
                                                                            "thing": "a",
                                                                            "data": 
                                                                                "text": "asdfsadf 2 6",
                                                                                "morestuff": "",
                                                                            ,
                                                                            "data": 
                                                                                "text": "asdfsadf 2 6",
                                                                                "morestuff": "",
                                                                            
                                                                        ,
                                                                    
                                                                ,
                                                            
                                                        ],
                                                    
                                                ,
                                            
                                        ],
                                    
                                ,
                            
                        ],
                    
                ,
            
        ,
        
            "thing": "a",
            "data": 
                "text": "asdfasd1 2",
                "morestuff": 
                    "thing": "Top",
                    "data": 
                        "childs": [
                            "thing": "a",
                            "data": 
                                "text": "asdfsadf 2 3",
                                "morestuff": "",
                            
                        ],
                    
                ,
            
        ,
        
            "thing": "a",
            "data": 
                "text": "dfghfdgh 4",
                "morestuff": "",
            
        ],
    
]  

...我正在尝试遍历它并获得“文本”对象的总数。

我似乎无法让递归工作..我想我缺少对 json 和递归的基本理解..

经过几天的变化:

count=0;
c2=0;
c3=0;
function ra(arr)
    //console.log(arr.data.morestuff)
    if(arr!==undefined && arr.data && arr.data.morestuff==="")
        c3++;

    else if((arr && arr.data && typeof arr.data.morestuff==="object"))
            if(arr.data.morestuff.data.childs.length>1)
                for(var w=0;w<arr.data.morestuff.data.childs.length;w++)
                    count+=ra(arr.data.morestuff.data.childs[w])
                
            else
                count+=ra(arr.data.morestuff.data.childs[0])
            
    
         return(c3)

countn=0;//top morestuff with no morestuff
tot=0;
function reps(obj)
tot=obj.data.childs.length;
console.log("tot="+tot)
    for(var x=0;x<tot;x++)
        tot+=ra(obj.data.childs[x])
        c3=0
        if(tot>1000)//trying to prevent a runaway loop somehwere
            break;
        
    
    console.log(tot)


reps(json[0]); 

我得出的结论是我不知道。我得到了各种不同的结果;有些通过将 ra 方法的返回相加而接近,但没有一致(即错误)并且总是至少相差一些。

JSON 是一致的,尽管有未知数量的孩子和孩子的孩子,这就是我寻求递归的原因。

这是一个小提琴:http://jsfiddle.net/CULVx/

理想情况下,我想计算每个文本对象、它的相对位置以及它拥有的子对象的数量,但我想如果我能让计数工作,我可以把这些东西放入一个数组中。 ..

注意:我尝试过 jsonParse 和其他库均无济于事。特别是,当试图在这个 json 上使用它时,jsonParse 会抛出一个Object has no method "match" 错误。

【问题讨论】:

您在最嵌套的对象中有两个 data 属性 - 对吗? @pimvdb 是的,但是在任何给定的 morestuff 属性中可以有任意数量的 data 道具 【参考方案1】:

如果您只想要 all "text"any 深度的属性,那么这应该足够了:http://jsfiddle.net/QbpqT/。

不过,您有两次属性键("data" 在最嵌套的对象中)。由于一个对象不能包含具有相同键的两个属性,因此您实际上有 9 个"text" 属性;不是 10。

var count = 0;

function iterate(obj) 
    for(var key in obj)  // iterate, `key` is the property key
        var elem = obj[key]; // `obj[key]` is the value

        if(key === "text")  // found "text" property
            count++;
        

        if(typeof elem === "object")  // is an object (plain object or array),
                                       // so contains children
            iterate(elem); // call recursively
        
    


iterate(data); // start iterating the topmost element (`data`)

console.log(count); // 9

【讨论】:

非常感谢!另外,很遗憾你这么快就回答了这个问题。 @stormdrain:对不起,我猜 :) @primvdb:我会让它滑动 :) 不过说真的,我有预感这是对 JSON 的概念性误解,你做了我没有找到的教程,没有实验,没有我找到的另一个答案是:用一段简单的代码简洁地解释它(并且在创纪录的时间内!)。再说一遍,说真的,谢谢你:) ...这绝对是我的“啊哈!” JSON 的时刻。 这不是迭代数组的方式,因为在某些浏览器中,原型属性和方法是可枚举的,并且会自行迭代。 甚至在性能良好的浏览器中,许多 js 库都会将属性添加到 Array.prototype 并且不关心将它们设置为不可枚举【参考方案2】:

这是使用object-scan的答案

// const objectScan = require('object-scan');

const data = ["thing":"Top","data":"childs":["thing":"a","data":"text":"sdfgdg1","morestuff":"thing":"Top","data":"childs":["thing":"a","data":"text":"sdfg2","morestuff":"","thing":"a","data":"text":"gfhjfghj3","morestuff":"thing":"Top","data":"childs":["thing":"a","data":"text":"asdfsadf 2 4","morestuff":"thing":"Top","data":"childs":["thing":"a","data":"text":"asdfsadf 2 5","morestuff":"thing":"Top","data":"childs":"thing":"a","data":"text":"asdfsadf 2 6","morestuff":""]]],"thing":"a","data":"text":"asdfasd1 2","morestuff":"thing":"Top","data":"childs":["thing":"a","data":"text":"asdfsadf 2 3","morestuff":""],"thing":"a","data":"text":"dfghfdgh 4","morestuff":""]];

const getCount = (obj) => objectScan(['**.text'],  rtn: 'count' )(obj);

console.log(getCount(data));
// => 9
.as-console-wrapper max-height: 100% !important; top: 0
&lt;script src="https://bundle.run/object-scan@13.7.1"&gt;&lt;/script&gt;

免责声明:我是object-scan的作者

【讨论】:

以上是关于递归问题;解析 JSON的主要内容,如果未能解决你的问题,请参考以下文章

使用 c# 递归解析 JSON

AngularJS将递归JSON解析为对象数组

在 Scala 中使用列表解析递归 JSON 结构

python小功能-递归解析Json

如何在没有外部递归函数的情况下解析多个嵌套的 JSON 键?

递归解析任意层的json