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



我正在尝试重新创建将字符串转换为嵌套对象的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}}),{}));

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

编写JSON.parse实现并不容易,因为 JSON 可以由大括号(或不大括号)、方括号(或不大括号)、带有转义序列的字符串、布尔值和数字原语组成......

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

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

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

您实际上不需要传递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。

最新更新