Переименование ключей json итеративное



Я получил очень простой json, но в каждом блоке я получил что-то вроде этого.



var json = {
"name": "blabla"
"Children": [{
"name": "something"
"Children": [{ ..... }]
}


И так далее. Я не знаю, сколько детей есть внутри каждого ребенка рекурсивно.



var keys = Object.keys(json);

for (var j = 0; j < keys.length; j++) {
var key = keys[j];
var value = json[key];
delete json[key];
key = key.replace("Children", "children");
json[key] = value;
}


А теперь я хочу заменить все ключи" Children "на строчные"children". Следующий код работает только для первой глубины. Как я могу сделать это рекурсивно?

766   4  

4 ответов:

Возможное решение:

var s = JSON.stringify(json);
var t = s.replace(/"Children"/g, '"children"');
var newJson = JSON.parse(t);
  • Плюсы: это очень простое решение, состоящее всего из трех строк.
  • Минусы: существует потенциальный нежелательный побочный эффект, рассмотрим:

    var json = {
      "name": "blabla",
      "Children": [{
        "name": "something",
        "Children": [{ ..... }]
      }],
      "favouriteWords": ["Children","Pets","Cakes"]
    }
    

Решение заменяетвсе экземпляры "Children", поэтому запись в массиве favouriteWords также будет заменена, несмотря на то, чтоне является именем свойства. Если нет никаких шансов, что слово появится где-то еще, кроме как свойство имя, то это не вопрос, но стоит поднять на всякий случай.

Похоже, что структура входных данных довольно хорошо определена, поэтому вы можете просто создать рекурсивную функцию, такую как:

function transform(node) {
  return {
    name: node.name,
    children: node.Children.map(transform)
  };
}


var json = {
  "name": "a",
  "Children": [{
    "name": "b",
    "Children": [{
      "name": "c",
      "Children": []
    }, {
      "name": "d",
      "Children": []
    }]
  }, {
    "name": "e",
    "Children": []
  }]
};

console.log(transform(json));

Вот функция, которая может делать это рекурсивно:

 function convertKey(obj) {
    for (objKey in obj)
    {

        if (Array.isArray(obj[objKey])) {
            convertKey[objKey].forEach(x => {
                convertKey(x);
            });

        }

        if (objKey === "Children") {
            obj.children = obj.Children;
            delete obj.Children;
        }
    }
 }

И вот более общий способ для этого:

function convertKey(obj, oldKey, newKey) {
    for (objKey in obj)
    {

        if (Array.isArray(obj[objKey])) {
            obj[objKey].forEach(objInArr => {
                convertKey(objInArr);
            });
        }

        if (objKey === oldKey) {
            obj[newKey] = obj[oldKey];
            delete obj[oldKey];
        }
    }
}

convertKey(json, "Children", "children");

И принятый ответ, и ответ @Tamas имеют небольшие проблемы.

С ответом @Bardy, как он указывает, есть проблема, если у кого-то из ваших ценностей было слово Дети, это вызвало бы проблемы.

С @Tamas одна проблема заключается в том, что любые другие свойства, кроме имени и детей, отбрасываются. Также он предполагает свойство детей. И что делать, если свойство children уже children, а не Children.

Используя слегка измененную версию @Tamas, это должно избежать подводные камни.

function transform(node) {
  if (node.Children) node.children = node.Children;
  if (node.children) node.children = node.children.map(transform);
  delete node.Children;
  return node;
}


var json = {
  "name": "a",
  "Children": [{
    "age": 13,
    "name": "b",
    "Children": [{
      "name": "Mr Bob Chilren",
      "Children": []
    }, {
      "name": "d",
      "age": 33,  //other props keep
      "children": [{
        "name": "already lowecased",
        "age": 44,
        "Children": [{
           "name": "now back to upercased",
           "age": 99
        }]
      }] //what if were alrady lowercased?
    }]
  }, {
    "name": "e",
    //"Children": []  //what if we have no children
  }]
};

console.log(transform(json));

Comments

    Ничего не найдено.