【问题标题】:Iterate through nested JSON tree and change values遍历嵌套的 JSON 树并更改值
【发布时间】:2016-02-16 23:32:17
【问题描述】:

我拥有的是以下结构的 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;
           });
       });
});

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

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

编辑:好的,我想这就是我需要的:JS/Jquery - using variable in json selector。我将“日期”部分更改为:formJSON.projects[projectName][selection][milestones] = document.getElementById(saltKey).value;这似乎有效。

【问题讨论】:

  • 这其实不是jquery,但是如果你熟悉angularjs,请查看json-tree指令。

标签: javascript jquery json


【解决方案1】:

我遇到了同样的问题,这是我迭代 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"
    } 
};

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • 这就是我认为的问题所在($.each 返回一个值而不是引用),但我真的不知道如何构建一个新的 JSON 对象。我一般都知道要创建新对象,但是如何添加嵌套级别?我之前尝试类似的问题时遇到的问题是在 JSON 引用中使用变量:var someNewThing = foo. 'JSONtree.someNewThing.default' 然后不返回 'JSONtree.foo.default' 的值
    • stackoverflow.com/questions/10919965/… 由于 JSON 对象本质上是数组,因此您可以像构建字符串索引数组一样构建它们。我建议也查看 JSON 的 Wikipedia 页面。 en.wikipedia.org/wiki/JSON
    • 嗯,所以我理解那部分,但是如何将变量作为 JSON 引用的一部分传递(myJSON.projects..milestones.)?
    • 好的,我想这就是我需要的:stackoverflow.com/questions/15432627/…。我将“日期”部分更改为:formJSON.projects[projectName][selection][milestones] = document.getElementById(saltKey).value;这似乎有效。谢谢!
    猜你喜欢
    • 2018-01-13
    • 1970-01-01
    • 2020-09-02
    • 1970-01-01
    • 2019-04-24
    • 1970-01-01
    • 2021-01-20
    • 1970-01-01
    • 2022-11-28
    相关资源
    最近更新 更多