Iterating through a nested JSON tree and changing values

I have a JSON tree with the following structure:

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

      

I have a code to read it in a webpage, with the "default" part in the text and numbers / dates in the textbox / form. The idea is that you can change the dates and send, which goes to the backend and is written to a file. This all works for the most part. I can figure out how to iterate through the JSON tree I have and write new values. For example:

Accessing JSONTREE.projects.Proj1.milestones.default returns the value for this key. Setting a value with this call changes the value accordingly. What I want to do is iterate over the entire tree and set the default values ​​depending on what is in the form window. I have it:

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

      

but it does nothing, although "alert (date)" returns a value. I suspect this is because it is a value and not an object reference, but how can I get to the object? I suspect it is simple, but I am not a jQuery / JS pro.

TL; DR How do I get references to a key in a nested JSON tree to change the value?

EDIT: Ok I think this is what I need: JS / Jquery - using a variable in a json selector . I changed the "date" part to: formJSON.projects [projectName] [select] [milestones] = document.getElementById (saltKey) .value; which seems to work.

+2


source to share


2 answers


Your edit to the passed value, not the original JSON object.

One way to fix this is to create a new JSON object, build as you iterate over the existing one, and then overwrite the original, or use the new JSON object.



Another is to create a var that stores the original JSON object and either pass it through your functions or access it directly inside the functions.

+1


source


I faced the same problem and this is my solution for iterating over a JSON object (MongoDB) and modifying certain elements regardless of whether those object properties or properties are an array with a lot of objects. I know the question is old, but it might be helpful to someone. Assuming we have such an object or even more complex one.

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"
  } 
};

      

And we want to replace some string (blue in this case), but we don't know where it is or what constructor our data has.

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

      

Now that we have these two functions, we use the third iteration over the element, regardless of whether it is an object or an array.

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

      

And the function that we should use to replace our string.



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

      

And finally, we get the result:

console.log(iterate(mixData));

      

Result:

{
    "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"
    } 
};

      

You can change the replacement function according to your needs. And, of course, delete all console logs.

+2


source







All Articles