用于将JSON中的嵌套对象更改为实际对象的递归函数

时间:2017-03-25 22:39:41

标签: javascript recursion

我试图重新创建将字符串转换为嵌套对象的JSON.parse()函数的一部分。

recNest(JSON.stringify({b:{c:2}})) //--> {b:{c:2}}

我认为最好的方法就是递归,我想我已经接近了,但有些事情已经结束了。到目前为止我已经写过这个函数了:

function recNest(string,obj){

  console.log(string);

  if(string){
    let pS,pE,kS,kE,key;
    pS = string.indexOf('{') + 1;
    pE = string.lastIndexOf('}') ;

    kS = string.indexOf('"')+1;
    kE = string.indexOf(':')-1;
    key = string.substr(kS,kE - kS);
    console.log(string.substr(pS,pE-pS));

    obj[key] = recNest(string.substr(pS,pE-pS),obj);
  }
  return obj;
}
console.log(recNest(JSON.stringify({b:{c:2}}),{}));

如果有一种方法可以在没有递归的情况下进行,我也会对此持开放态度。

1 个答案:

答案 0 :(得分:1)

编写JSON.parse实现并不容易,因为JSON可以包括大括号(或不包括),方括号(或不包含),带有转义序列的字符串,布尔和数字基元,...

对于要解析的值,您的代码有两个问题:

  1. 传递给递归调用的字符串值不再是有效的JSON,因为它仍然包含非实体字符串文字的键。它应该只是值部分(在冒号之后)。

  2. 当递归结束时,当字符串值表示原始值时,没有好的返回值:它是函数应该返回的值。

  3. 你实际上并不需要传递 obj :它应该在每个递归级别从头开始。聚合在递归调用返回时完成。

    以下是您的代码,其中包含一些注释更正:

    function recNest(string){ // No need for second argument
        let pS,pE,kS,kE,key,obj;
    
        // Always check the presence of the brace
        pS = string.indexOf('{') + 1;
        if(pS){ 
            pE = string.lastIndexOf('}') ;
            kS = string.indexOf('"')+1;
            kE = string.indexOf(':')-1;
            key = string.substr(kS, kE - kS);
            //Corrected substr arguments: only the value part should be passed
            obj = { [key]: recNest(string.substr(kE+2,pE-(kE+2))) };
        } else { // Assume it is a primitive value
            obj = string;
        }
        return obj;
    }
    

    注意:进一步扩展它以支持更多JSON文本当然超出了本问题的范围。有很好的库可以解析JSON。例如JSON 3