迭代嵌套的JSON树并更改值

时间:2014-06-16 19:08:58

标签: javascript jquery json

我所拥有的是具有以下结构的JSON树:

{
    "projects": {
        "Proj1": {
            "milestones": {
                "default": "20150101",
                "default2": "20140406",
                "default3": "20140101",
                "default4": "20131231",
                "default5": "20131220"
            }
        },
        "Proj2": {
            "milestones": {
                "default": "20131231",
                "default2": "20131220"
            }
        }
    }
}

我有代码可以将其读入网页,其中包含'默认'部分在文本中,数字/日期在文本框/表单中。这个想法是你可以改变日期并提交,然后提交到后端并写入文件。所有这些在大多数情况下都有效。我能弄清楚的是如何遍历我拥有的JSON树并编写新值。例如:

访问JSONTREE.projects.Proj1.milestones.default会返回该键的值。使用该调用设置值会适当地更改该值。我想要做的是遍历整个树并设置'默认值'基于表格框中的内容。我有这个:

$.each(formJSON.projects, function (projectName) {
        $.each(this, function (selection) {
            $.each(this, function (milestones, date) {
                var saltKey = projectName + "-" + milestones;
                date = document.getElementById(saltKey).value;
           });
       });
});

但它什么也没做,即使'警告(日期)'返回一个值。我怀疑这是因为它是值,而不是对象的引用,但我怎样才能找到对象?我怀疑它很简单,但我不是jQuery / JS的专家。

TL; DR如何在嵌套的JSON树中获取对键的引用,以便我可以更改值?

编辑:好的,我认为这就是我需要的:JS/Jquery - using variable in json selector。我改变了日期' part to:formJSON.projects [projectName] [selection] [里程碑] = document.getElementById(saltKey).value;这似乎有效。

2 个答案:

答案 0 :(得分:2)

我遇到了同样的问题,这是我的迭代JSON对象(MongoDB)并修改某些元素的解决方案,无论这些元素是对象的属性还是属性是具有更多对象的数组。我知道这个问题很老,但对某人来说这可能很有用。 假设我们有这样的对象,甚至更复杂。

var mixData = {
  "Hello": "World",
  "Foo" : "Bar",
  "sudo": [
    { "apt-get": "upgrade" , "force": false },
    { "apt-get": "update" , "force": true}
  ],
  "colors": ["blue","green"],
  "numbers":{
    "integer": [
      {"num": 1},
      {"num": 2},
      {"num": 3}
    ],
    "operator": "addition"
  } 
};

我们想要替换一些字符串(在这种情况下为蓝色),但我们不知道构造函数的位置或数据的类型。

// Detect if the element is an Array
function isElementArray(element){
  return (element.constructor === Array ? true : false);
}
//Detect if the element is an Object
function isElementObject(element){
  return (element.constructor === Object ? true : false);
}

既然我们有这两个函数,我们使用第三个函数迭代项目,无论是对象还是数组。

function iterate(element){
  //Check if the element is an Object
  if(isElementObject(element)){
    for (var property in element){
      if(isElementObject(element[property])){
        element[property] = iterate(element[property]);
      }else if(isElementArray(element[property])){
        //An array
        for(var x = 0; x < element[property].length; x++){
          element[property][x] = iterate(element[property][x]);
        }
      }else{
        if(element.hasOwnProperty(property)){
          console.log("New object inside object property");
          element[property] = iterate(element[property]);
        }else{
          element[property] = replaceElement(element[property].toString());
          console.log("Single Element: " + element[property] )
          console.log(element + " " + element[property]);
        }
      }
    }
  }else if(isElementArray(element)){
    //An Array
    for (var x = 0; x < element.length; x++){
      element[x] = iterate(element[x]);
    }
  }else{
    //Single element in array or property
    element = replaceElement(element.toString());
    console.log("Single Element : " + element);
  }
  return element;
}

我们需要用来替换字符串的函数。

function replaceElement(element){
  if(element === "blue"){
    return "Blue is the warmest color"
  }else{
    return element;
  }
}

最后,我们可以得到结果:

console.log(iterate(mixData));

结果是:

{
    "Hello": "World",
    "Foo" : "Bar",
    "sudo": [
      { "apt-get": "upgrade" , "force": false },
      { "apt-get": "update" , "force": true}
    ],
    "colors": ["Blue is the warmest color","green"],
    "numbers":{
      "integer": [
        {"num": 1},
        {"num": 2},
        {"num": 3}
      ],
      "operator": "addition"
    } 
};

您可以更改替换功能以满足您的需求。当然,删除控制台日志。

答案 1 :(得分:1)

您编辑传递的值而不是原始JSON对象。

解决此问题的一种方法是创建一个新的JSON对象,在遍历现有JSON对象时进行构建,然后覆盖原始对象或使用新的JSON对象。

另一种方法是创建一个包含原始JSON对象的var,并将其传递给函数或直接在函数内部访问它。