7

I have a JSON data structure as shown below:

{
    "name": "World",
    "children": [
      { "name": "US",
          "children": [
           { "name": "CA" },
           { "name": "NJ" }
         ]
      },
      { "name": "INDIA",
          "children": [
          { "name": "OR" },
          { "name": "TN" },
          { "name": "AP" }
         ]
      }
 ]
};

I need to change the key names from "name" & "children" to say "key" & "value". Any suggestion on how to do that for each key name in this nested structure?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
user1842231
  • 213
  • 1
  • 3
  • 8

3 Answers3

16

I don't know why you have a semicolon at the end of your JSON markup (assuming that's what you've represented in the question), but if that's removed, then you can use a reviver function to make modifications while parsing the data.

var parsed = JSON.parse(myJSONData, function(k, v) {
    if (k === "name") 
        this.key = v;
    else if (k === "children")
        this.value = v;
    else
        return v;
});

DEMO: http://jsfiddle.net/BeSad/

I Hate Lazy
  • 47,415
  • 13
  • 86
  • 77
  • 1
    thank you. your code is working perfect. Sorry for semicolon at the end. It was a typo, but I've learned so much from this mistake. – user1842231 Nov 22 '12 at 20:55
  • @IHateLazy: I see something new like changing the key but may I know where is this function so that I can more in details. And if I want to add number to the key in the for loop, I seem can't get it to work like -- this.batchi.concat(string(i)) = v; where i is incrementing in the for loop. – user1739825 May 09 '13 at 00:55
  • 1
    @IHateLazy: Please refer to [link](http://stackoverflow.com/questions/16435711/javascript-using-reviver-function-i-seem-cant-get-to-alter-all-the-keys-whil). – user1739825 May 09 '13 at 01:05
  • Does anyone know why dots cannot be replaced in the key name, but any other letter can? https://jsfiddle.net/dpiret/dgk5fp16/5/ – daniel p Jun 24 '21 at 11:06
  • @danielp why did you use k.search? That function works with regex (so providing it with '.' gave you unexpected results. You probably wanted to use k.indexOf('.') – targumon Jun 17 '23 at 19:51
0

You could use a function like this :

function clonerename(source) {
    if (Object.prototype.toString.call(source) === '[object Array]') {
        var clone = [];
        for (var i=0; i<source.length; i++) {
            clone[i] = goclone(source[i]);
        }
        return clone;
    } else if (typeof(source)=="object") {
        var clone = {};
        for (var prop in source) {
            if (source.hasOwnProperty(prop)) {
                var newPropName = prop;
                if (prop=='name') newPropName='key';
                else if (prop=='children') newPropName='value';
                clone[newPropName] = clonerename(source[prop]);
            }
        }
        return clone;
    } else {
        return source;
    }
}

var B = clonerename(A);

Note that what you have isn't a JSON data structure (this doesn't exist as JSON is a data-exchange format) but probably an object you got from a JSON string.

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • The only thing I see that would disqualify it as valid JSON markup is the semicolon *(I have no idea why that's there)*. Other than that, why wouldn't this be valid JSON? – I Hate Lazy Nov 22 '12 at 19:18
  • Because JSON is a *string* format. This is probably a simple javascript object, it's only missing some `var a =` before. hence the `;`. – Denys Séguret Nov 22 '12 at 19:21
  • dystroy: Yes, JSON is a text format, but that doesn't mean this isn't some JSON markup sitting in a file on the server, again except for that semicolon. It's really not valid either way as shown. – I Hate Lazy Nov 22 '12 at 19:24
  • ...but I guess I'd agree that the `;` could make me lean that way. – I Hate Lazy Nov 22 '12 at 19:24
0

Try this:

function convert(data){
  return {
    key: data.name,
    value: data.children.map(convert);
  };
}

Or if you need to support older browsers without map:

function convert(data){
  var children = [];
  for (var i = 0, len = data.children.length; i < len; i++){
    children.push(convert(data.children[i]));
  }

  return {
    key: data.name,
    value: children
  };
}
loganfsmyth
  • 156,129
  • 30
  • 331
  • 251