Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/412.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.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_Json_Dictionary - Fatal编程技术网

将javascript字典转换为JSON格式

将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",

我有一本javascript字典:

{
  "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在根目录下有两个名称,会发生什么呢?我主动返回了一份清单。但是提取我输出的第一个元素总是可能的。这是一个很好的计划,谢谢你的澄清。我认为在你的回答中添加这一点很重要,因为如果没有这一澄清,在评论中很可能就足够了,那么期望的内容和交付的内容之间就存在差异。然而,你添加它是正确的,我没有一路思考,我道歉!不道歉。你是对的,我应该在答案中证明这一点。很好的错误处理,显然我们其他人没有想到处理异常输入错误处理,显然我们其他人没有想到处理异常输入