1

I have object like this which contains many keys named label and choices:

const obj = {
  "label": "mylabel",
  "choices": [
    {
      "label": "mylabel_11",
      "choices": {
        "label": "mylabel_12",
        "choices": [ /* … */ ]
      }
    },
    {
      "label": "mylabel_21",
      "choices": {
        "label": "mylabel_22",
        "choices": [ /* … */ ]
      }
    },
  ]
}

I want to change all "label" to "name", and all "choices" to "children".

Is there any recursive way to replace the name?

Currently my idea is this:

const new_keys = {};

for (const key in obj) {
  const old_key = key;

  key = key.replace("label", "name");
  key = key.replace("choices", "children");
  new_keys[key] = obj[old_key]
}

How can I make this recursive?

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
whitebear
  • 11,200
  • 24
  • 114
  • 237

3 Answers3

3

IMHO the easiest way would be to use string.replace. All code in one line

var obj=JSON.parse(JSON.stringify(obj).replaceAll("\"label\":","\"name\":")
.replaceAll("\"choices\":","\"children\":"));

result

{
  "name": "mylabel",
  "children": [
    {
      "name": "mylabel_11",
      "children": {
        "name": "mylabel_12",
        "children": []
      }
    },
    {
      "name": "mylabel_21",
      "children": {
        "name": "mylabel_22",
        "children": []
      }
    }
  ]
}
Serge
  • 40,935
  • 4
  • 18
  • 45
2

You could look to use recursion in the following way, noting that the if statement accounts for the fact that your object's "choices" can be either an array or an object.

function replaceObject(yourObj) {
    if (yourObj.hasOwnProperty("label")) {
        if (Array.isArray(yourObj.choices)) {
            return {
                name: yourObj.label,
                children: yourObj.choices.map((choice) => {
                    return replaceObject(choice);
                }),
            };
        } else {
            return {
                name: yourObj.label,
                children: replaceObject(yourObj.choices),
            };
        }
    }
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
1

I think you're asking for a way to make it go arbitrarily deep into your object. I think this could work:

function recursiveKeyRename(obj) {
  var new_keys;
  for (key in obj){
    var old_key = key;
    key = key.replace("label","name");
    key = key.replace("choices","children");
    new_keys[key] = obj[old_key]
  };
  if (obj.children && obj.children.choices)
  {
    recursiveKeyRename(obj.children.choices)
  };
};

I haven't really tested that, and that only works if all of you "choices" are objects, not arrays like you (maybe?) implied in your example. It can easily be retooled for whichever use case, though.

  • 1
    Thank you it cloud be helpful to understand recursive.it's quit simple way. – whitebear Feb 17 '22 at 02:41
  • The most important thing to know about recursive functions like this is there always needs to be an escape solution. Javascript (and most languages that allow recursion) will allow you to write the recursive function without the if statement...but then it will try to run forever. Always be sure to define exactly how the function escapes. – RadicalTurnip Feb 17 '22 at 18:07