将javascript字典转换为JSON格式
我有一本javascript字典:将javascript字典转换为JSON格式,javascript,json,dictionary,Javascript,Json,Dictionary,我有一本javascript字典: { "a": { "b": { "c": null, "d": null } } } 如何将其转换为可以指定名称和子属性的JSON对象?有什么优雅的方法吗? JSON对象可以是: { name:"a" children: [{ name:"b", children: [{ name:"c",
{
"a": {
"b": {
"c": null,
"d": null
}
}
}
如何将其转换为可以指定名称和子属性的JSON对象?有什么优雅的方法吗?
JSON对象可以是:
{
name:"a"
children: [{
name:"b",
children: [{
name:"c",
children: null
},{
name:"d",
children: null}]
}]
}
您可以创建一个递归函数来生成输出:
var x = {
"a": {
"b": {
"c": null,
"d": null
}
}
};
function generate(item, key) {
var result = {
name: key,
children: []
};
for (var _ in item)
result.children.push(generate(item[_], _))
if (result.children.length == 0)
result.children = null;
return (key == undefined) ? result.children : result;
}
console.log(JSON.stringify(generate(x), null, 1));
输出:
[
{
"name": "a",
"children": [
{
"name": "b",
"children": [
{
"name": "c",
"children": null
},
{
"name": "d",
"children": null
}
]
}
]
}
]
上面的generate函数返回一个列表而不是字典,因为在根级别可能有多个名称。但是,如果我们确定根名称中只有一个名称,我们可以像下面这样生成json:
console.log(JSON.stringify(generate(x)[0], null, 1));
generate(obj)[0]
您可以创建一个递归函数来生成输出:
var x = {
"a": {
"b": {
"c": null,
"d": null
}
}
};
function generate(item, key) {
var result = {
name: key,
children: []
};
for (var _ in item)
result.children.push(generate(item[_], _))
if (result.children.length == 0)
result.children = null;
return (key == undefined) ? result.children : result;
}
console.log(JSON.stringify(generate(x), null, 1));
输出:
[
{
"name": "a",
"children": [
{
"name": "b",
"children": [
{
"name": "c",
"children": null
},
{
"name": "d",
"children": null
}
]
}
]
}
]
上面的generate函数返回一个列表而不是字典,因为在根级别可能有多个名称。但是,如果我们确定根名称中只有一个名称,我们可以像下面这样生成json:
console.log(JSON.stringify(generate(x)[0], null, 1));
generate(obj)[0]
这是我的解决办法。它类似于JuniorCompressor的
function generate(obj) {
// Return primitives as-is
if (!(obj instanceof Object)) return obj;
// Loop through object properties and generate array
var result = [];
for (var key in obj) {
result.push({
name: key,
children: generate(obj[key])
});
}
// Return resulting array
return result;
}
如前所述,如果原始对象中有多个根级别属性,则生成的对象实际上将是一个数组。如果确实需要生成的对象是仅具有属性名称和值的对象,则应访问生成数组的第一个元素,如下所示:
console.log(JSON.stringify(generate(x)[0], null, 1));
generate(obj)[0]
这是我的解决办法。它类似于JuniorCompressor的
function generate(obj) {
// Return primitives as-is
if (!(obj instanceof Object)) return obj;
// Loop through object properties and generate array
var result = [];
for (var key in obj) {
result.push({
name: key,
children: generate(obj[key])
});
}
// Return resulting array
return result;
}
如前所述,如果原始对象中有多个根级别属性,则生成的对象实际上将是一个数组。如果确实需要生成的对象是仅具有属性名称和值的对象,则应访问生成数组的第一个元素,如下所示:
console.log(JSON.stringify(generate(x)[0], null, 1));
generate(obj)[0]
解决方案
您需要一个递归函数,它为子函数调用自身。请注意,在您的示例中,只有一个顶级子级a。相反,我使用的假设是顶级“name”指的是实际对象本身的名称。如果希望从名为“obj”的对象中获得与演示完全相同的结果,请运行toJSONobj.children[0]。对于整个函数,请尝试以下操作:
function toJSON(obj, name) {
var subTree = {
name: name,
children: []
};
if (obj !== null && Object.keys(obj).length >= 1) {
for (var child in obj) {
subTree.children.push(toJSON(obj[child], child));
}
} else {
subTree.children = null;
}
return subTree;
}
toJSONobj.children的结果[0]:
{
"name": "a",
"children": [{
"name": "b",
"children": [{
"name": "c",
"children": null
},{
"name": "d",
"children": null
}]
}]
}
toJSONobj‘obj’的结果:
{
"name": "obj",
"children": [{
"name": "a",
"children": [{
"name": "b",
"children": [{
"name": "c",
"children":null
},
{
"name": "d",
"children": null
}]
}]
}]
}
以下是逐行解释:
声明函数,该函数需要两个参数:对象和名称。但是,如果您要使用toJSONobj.children[0],则不必考虑第二个参数。这不会影响结果。
声明结果,该对象包含有关对象中当前级别和以下所有级别的信息。如果将对象视为树,则此结果包含当前分支及其所有分支的信息。
声明属性“name”,其中包含当前级别的对象的名称/键。调用函数时,需要将名称作为第二个参数包含在内,因为无法动态查找变量的名称。它们通过值传递到函数中。但是,如上所述,如果您正在寻找与示例中完全相同的结果,那么您将使用toJSONobj.children[0],而不是toJSONobj'obj',然后不需要麻烦第二个参数。
声明要在下面填充的子数组
终止从第2行开始的声明
检查对象是否为null,并且它是否有子对象,如果是,则使用一个方便的方法运行第7、8和9行
迭代对象的子对象,为每个子对象运行第8行
递归地为每个子级运行toJSON函数,以获取其子树。因为孩子们不能动态地计算出他们自己的名字,所以它也会传递这些名字。
终止从第7行开始的for循环
如果没有孩子,运行第11行。仅当第7行、第8行和第9行未运行时,才运行此操作。
根据第6行的检查,将子项设置为空,仅在没有子项时运行
终止从第10行开始的else
返回当前子树,如果函数递归调用,则返回给函数;如果您自己调用,则返回给您
终止函数
有关上一版本的信息,预编辑
原始函数只使用了一个参数,而上面的函数有另一个“name”参数。这是因为原始版本试图找出同一级别中每个级别的名称,而我后来意识到这在Javascript中是不可能的。基本上,原稿不起作用,必须添加一个额外的参数才能起作用。不过,为了记录起见,最初的功能是:
// THIS FUNCTION DOESN'T WORK. IT'S HERE ONLY FOR HISTORICAL ACCURACY:
function toJSON(obj) {
var subTree = {
name: obj.constructor.name, // This should get the object key
children: []
};
if (Object.keys(obj).length >= 1) { // If there is at least one child
for (var child in obj) {
subTree.children.push(toJSON(obj[child]));
}
} else {
subTree.children = null;
}
return subTree;
}
解决方案
您需要一个递归函数,它为子函数调用自身。请注意,在您的示例中,只有一个顶级子级a。相反,我使用的假设是顶级“name”指的是实际对象本身的名称。如果希望从名为“obj”的对象中获得与演示完全相同的结果,请运行toJSONobj.children[0]。对于整个函数,请尝试以下操作:
function toJSON(obj, name) {
var subTree = {
name: name,
children: []
};
if (obj !== null && Object.keys(obj).length >= 1) {
for (var child in obj) {
subTree.children.push(toJSON(obj[child], child));
}
} else {
subTree.children = null;
}
return subTree;
}
toJSONobj.children的结果[0]:
{
"name": "a",
"children": [{
"name": "b",
"children": [{
"name": "c",
"children": null
},{
"name": "d",
"children": null
}]
}]
}
toJSONobj‘obj’的结果:
{
"name": "obj",
"children": [{
"name": "a",
"children": [{
"name": "b",
"children": [{
"name": "c",
"children":null
},
{
"name": "d",
"children": null
}]
}]
}]
}
以下是逐行解释:
声明函数,该函数
expects两个参数:对象及其名称。但是,如果您要使用toJSONobj.children[0],则不必考虑第二个参数。这不会影响结果。
声明结果,该对象包含有关对象中当前级别和以下所有级别的信息。如果将对象视为树,则此结果包含当前分支及其所有分支的信息。
声明属性“name”,其中包含当前级别的对象的名称/键。调用函数时,需要将名称作为第二个参数包含在内,因为无法动态查找变量的名称。它们通过值传递到函数中。但是,如上所述,如果您正在寻找与示例中完全相同的结果,那么您将使用toJSONobj.children[0],而不是toJSONobj'obj',然后不需要麻烦第二个参数。
声明要在下面填充的子数组
终止从第2行开始的声明
检查对象是否为null,并且它是否有子对象,如果是,则使用一个方便的方法运行第7、8和9行
迭代对象的子对象,为每个子对象运行第8行
递归地为每个子级运行toJSON函数,以获取其子树。因为孩子们不能动态地计算出他们自己的名字,所以它也会传递这些名字。
终止从第7行开始的for循环
如果没有孩子,运行第11行。仅当第7行、第8行和第9行未运行时,才运行此操作。
根据第6行的检查,将子项设置为空,仅在没有子项时运行
终止从第10行开始的else
返回当前子树,如果函数递归调用,则返回给函数;如果您自己调用,则返回给您
终止函数
有关上一版本的信息,预编辑
原始函数只使用了一个参数,而上面的函数有另一个“name”参数。这是因为原始版本试图找出同一级别中每个级别的名称,而我后来意识到这在Javascript中是不可能的。基本上,原稿不起作用,必须添加一个额外的参数才能起作用。不过,为了记录起见,最初的功能是:
// THIS FUNCTION DOESN'T WORK. IT'S HERE ONLY FOR HISTORICAL ACCURACY:
function toJSON(obj) {
var subTree = {
name: obj.constructor.name, // This should get the object key
children: []
};
if (Object.keys(obj).length >= 1) { // If there is at least one child
for (var child in obj) {
subTree.children.push(toJSON(obj[child]));
}
} else {
subTree.children = null;
}
return subTree;
}
你需要编写一个递归函数。我不确定这是不是有意的,但这是我第一次在一篇文章中看到JSON对象,这篇文章并没有让我对JSON字符串与JavaScript对象之间的关系感到愤怒。好极了,也就是说,你的JSON对象不是有效的JSON;键也需要用双引号括起来。很抱歉造成混淆,请更改问题您将需要编写一个递归函数。我不确定这是有意的,但这是我第一次在一篇文章中看到JSON对象,这篇文章并没有让我对JSON字符串与JavaScript对象之间的关系感到愤怒。好极了,也就是说,你的JSON对象不是有效的JSON;键也需要用双引号括起来。很抱歉造成混淆,请更改问题。这非常接近,因此是upvote,但是您的JSON与目标稍有不同,您在根目录下的输出应该是{…}而不是[{…}]是,但是如果OP在根目录下有两个名称,会发生什么情况?我主动返回了一份清单。但是提取我输出的第一个元素总是可能的。这是一个很好的计划,谢谢你的澄清。我认为在你的回答中添加这一点很重要,因为如果没有这一澄清,在评论中很可能就足够了,那么期望的内容和交付的内容之间就存在差异。然而,你添加它是正确的,我没有一路思考,我道歉!不道歉。你是对的,我应该在答案中证明它是正确的。这非常接近,因此是upvote,但是你的JSON与目标稍有不同,你在根目录下的输出应该是{…}而不是[{…}]是的,但是如果OP在根目录下有两个名称,会发生什么呢?我主动返回了一份清单。但是提取我输出的第一个元素总是可能的。这是一个很好的计划,谢谢你的澄清。我认为在你的回答中添加这一点很重要,因为如果没有这一澄清,在评论中很可能就足够了,那么期望的内容和交付的内容之间就存在差异。然而,你添加它是正确的,我没有一路思考,我道歉!不道歉。你是对的,我应该在答案中证明这一点。很好的错误处理,显然我们其他人没有想到处理异常输入错误处理,显然我们其他人没有想到处理异常输入