Форматирование данных json для camelCased
Я получаю ответ json от сервера, который выглядит примерно так:
{
"Response": {
"FirstName": "John",
"LastName": "Smith",
"NickNames": {
"NameOne": "Johnny",
"NameTwo": "JohnS",
"NameThree": "Smithy"
},
"Success": true,
"Errors": []
}
}
Есть ли способ запустить этот ответ через функцию, чтобы ключ каждой пары значений ключа был бы camelCased?
Таким образом, результат будет выглядеть примерно так:
{
"Response": {
"FirstName": "John",
"LastName": "Smith",
"NickNames": {
"NameOne": "Johnny",
"NameTwo": "JohnS",
"NameThree": "Smithy"
},
"Success": true,
"Errors": []
}
}
Если кто-то может указать мне в правильном направлении, это будет здорово.
Спасибо.
Ответы
Ответ 1
Вы передадите JSON.parse
функцию reviver, которая присваивает значения новым свойствам, расположенным ниже.
function reviver(key, val) {
if (key)
this[key.charAt(0).toLowerCase() + key.slice(1)] = val;
else
return val;
}
var parsed = JSON.parse(myjson, reviver);
Итак, если key
имеет по крайней мере один символ, он будет вводить нижний регистр первого символа и добавлять остальное и добавлять этот ключ к объекту и разрешать функции возвращать undefined
, чтобы исходный ключ не используется.
Если key
не имеет символов, он просто возвращает значение для исходной обработки.
DEMO: http://jsfiddle.net/GrupQ/
Ответ 2
Подход, который предложил пользователь "@I Hate Lazy", с использованием функции "reviver" - правильный. Однако его функция не работала для меня.
Возможно, это потому, что я разбираю массив JSON. Также я использую Resharper, и он жаловался на запах кода:) ('не все пути кода возвращают значение'). Поэтому я использовал функцию из другой проблемы SO, которая сделала для меня:
function camelCaseReviver(key, value) {
if (value && typeof value === 'object') {
for (var k in value) {
if (/^[A-Z]/.test(k) && Object.hasOwnProperty.call(value, k)) {
value[k.charAt(0).toLowerCase() + k.substring(1)] = value[k];
delete value[k];
}
}
}
return value;
}
Ответ 3
Как @Bart говорит, @I Hate Lazy reviver метод не способен анализировать массивы. Вот функциональный рекурсивный (ES6) подход.
function convertKeysToCamelCase(o) {
if (o === null) {
return null;
} else if (o === undefined) {
return undefined;
} else if (Array.isArray(o)) {
return o.map(convertKeysToCamelCase);
}
return Object.keys(o).reduce((prev, current) => {
const newKey = `${current[0].toLowerCase()}${current.slice(1)}`;
if (typeof o[current] === 'object') {
prev[newKey] = convertKeysToCamelCase(o[current]);
} else {
prev[newKey] = o[current];
}
return prev;
}, {});
}
Ответ 4
@adamjyee Ваше решение работает, за исключением вложенного массива целых чисел. Небольшое исправление может быть:
function convertKeysToCamelCase (o) {
if (o === null) {
return null
} else if (o === undefined) {
return undefined
} else if (typeof o === 'number') {
return o
} else if (Array.isArray(o)) {
return o.map(convertKeysToCamelCase)
}
return Object.keys(o).reduce((prev, current) => {
const newKey = `${current[0].toLowerCase()}${current.slice(1)}`
if (typeof o[current] === 'object') {
prev[newKey] = convertKeysToCamelCase(o[current])
} else {
prev[newKey] = o[current]
}
return prev
}, {})
[Право прокомментировать, но не имеет права голоса: (]
Ответ 5
Вам нужно написать рекурсивную функцию, которая пересекает дерево и возвращает новое дерево, в котором были обновлены ключи в объектах. Рекурсивная функция называла бы себя с любыми подобъектами, с которыми она сталкивается.