将javascript字典转换为JSON格式

时间:2015-03-06 19:00:22

标签: javascript json dictionary

我有一个javascript词典:

{
  "a": {
      "b": {
          "c": null,
          "d": null
           }
       }
}

如何将其转换为JSON对象,我可以指定名称和子属性?有没有优雅的方法呢? JSON对象可以是:

{
    name:"a"
    children: [{
      name:"b",
      children: [{
          name:"c",
          children: null
           },{
          name:"d",
          children: null}]
       }]
  }

3 个答案:

答案 0 :(得分:3)

您可以创建一个递归函数来生成输出:

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));

答案 1 :(得分:2)

这是我的解决方案。它与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;
}

如上所述,生成的对象实际上是一个数组(如果原始对象中有多个根级属性)。如果您确实需要生成的对象是仅具有属性名称和值的对象,那么您应该访问结果数组的第一个元素,如下所示:

generate(obj)[0]

答案 2 :(得分:1)

解决方案

你需要一个递归函数,它为孩子们调用自己。请注意,在您的示例中,只有一个顶级子级(a)。我改为使用顶级“名称”引用实际对象本身名称的假设。如果你想获得与你演示的结果完全相同的结果,从名为'obj'的对象,运行到JSON(obj).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;
}

toJSON(obj)的结果.children [0]:

{
    "name": "a",
    "children": [{
        "name": "b",
        "children": [{
            "name": "c",
            "children": null
        },{
            "name": "d",
            "children": null
        }]
    }]
}

toJSON(obj,'obj')的结果:

{
    "name": "obj",
    "children": [{
        "name": "a",
        "children": [{
            "name": "b",
            "children": [{
                "name": "c",
                "children":null
            },
            {
                "name": "d",
                "children": null
            }]
        }]
    }]
}

以下是逐行说明:

  1. 声明函数,它需要两个参数:对象及其名称。但是,如果您要使用toJSON(obj).children [0],请不要理会第二个参数。它不会影响结果。
  2. 声明结果,该对象包含有关当前级别和对象中下面所有级别的信息。如果您将对象视为树,则此结果包含有关当前分支及其所有分支的信息。
  3. 声明属性'name',包含当前级别对象的名称/键。调用函数时,需要将名称包含为第二个参数,因为无法动态查找变量的名称。它们按价值传递给功能。但是,如上所述,如果您正在寻找与示例中的结果完全相同的结果,那么您将使用toJSON(obj).children [0],而不是toJSON(obj,'obj'),然后不要不需要打扰第二个论点。
  4. 声明子数组,在
  5. 下面填充
  6. 终止在第2行开始的声明
  7. 使用Object built-in object的方便方法检查对象是否为空,并且它是否为子节点,如果是,则运行第7,8和9行
  8. 迭代对象的子项,为每个孩子运行第8行
  9. 递归运行每个子节点的toJSON()函数,以获取它的subTree。因为孩子们不能动态地找出他们自己的名字,所以它也会传递给他们。
  10. 终止从第7行开始的for循环
  11. 如果没有孩子,请运行第11行。只有在第7,8和9行不行时才会运行。
  12. 将子项设置为null(仅在没有子项时运行,由第6行检查)
  13. 终止从第10行开始的其他内容
  14. 返回当前的subTree,如果函数以递归方式调用,则返回函数;如果自己调用,则返回给您
  15. 终止功能
  16. 有关先前版本的信息,预编辑

    原始函数只使用了一个参数,而上面的函数有另一个参数'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;
    }