I get a json response from the server that looks something like this:
{
\"Response\": {
\"FirstName\": \"John\",
\"LastName\": \"Smith\",
@adamjyee Your solution works except for nested array of integers. A small fix could be:
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
}, {})
[Right to comment but lacking comment priviledge :(]
You would give JSON.parse
a reviver function that assigns values to new properties that are lower-cased.
function toCamelCase(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;
}
var parsed = JSON.parse(myjson, toCamelCase);
More information about how it works in this SO answer.
The approach that user '@I Hate Lazy' suggested - using a 'reviver' function is - the right one. However his function didn't work for me.
Perhaps it is because I'm parsing a JSON array. Also I use Resharper and it complained about a code smell :) ('not all code paths return a value'). So I ended up using a function from another SO issue which did work for me:
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;
}
Here is a functional recursive (ES6) approach.
function convertKeysToCamelCase(o) {
if (o === null || o === undefined) {
return o;
} else if (Array.isArray(o)) {
return o.map(convertKeysToCamelCase);
}
return typeof o !== 'object' ? o : 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;
}, {});
}
// successfully tested input
const o = {
SomeNum: 1,
SomeStr: 'a',
SomeNull: null,
SomeUndefined: undefined,
SomeBoolean: true,
SomeNaN: NaN,
NestedObject: {
SomeSentence: 'A is for apple',
AnotherNested: {
B: 'is for blahblah'
}
},
NumArray: [1, 2, 3, 4],
StringArray: ['a', 'b', 'c'],
BooleanArray: [true, false],
ArrayOfArrays: [[1,2,], ['a','b']],
ObjectArray: [{Foo:'bar'}, {Hello:'world', Nested:{In:'deep'}}],
MixedArray: [1,'a', true, null, undefined, NaN, [{Foo:'bar'}, 'wat']]
}
const output = convertKeysToCamelCase(o);
console.log(output.mixedArray[6][0].foo); // 'bar'
You need to write a recursive function that traverses the tree and returns a new tree where the keys in the objects have been updated. The recursive function would call itself to deal with any sub-objects it encounters.