Related
I wanna access the properties and their values of an object dynamically, the scenario is:
const SoldeN = {
1:4,
}
const SoldeN_1 = {
2:5,
}
const soldes = [
{ formula: '=SoldeN("1")',value:0},
{ formula: '=SoldeN_1("2")',value:0},
{ formula: '=SoldeN_1("1")+SoldeN_1("2")',value:0},
];
What I've tried so far:
const getProperty = string => string.match(/\(.*?\)/g).map(x => x.replace(/[(")]/g, ''))
const getObject = string => string.match(/[=+](.*?)\(/g).map(x => x.replace(/[=(+]/g, ''))
console.log(soldes.map(solde=>[getObject(solde.formula),getProperty(solde.formula)]))
[
[["SoldeN"], ["1"]],
[["SoldeN_1"], ["2"]],
[
["SoldeN_1", "SoldeN_1"],
["1", "2"],
],
];
Till now Everything is ok, but To get the value of an object dynamically based on property I used this function:
const getPropertyValue = (obj, prop) => obj[prop];
getPropertyValue('SoldeN','1')
//'o'
It gives me 'o' instead of 1, I know If I've passed the reference of an object it bring its value; but to get it dynamically I've to pass the actual name of an object which is string, not the object reference.
The expected Result would be:
result = [
{ formula: '=SoldeN("1")',value:4},
{ formula: '=SoldeN_1("2")',value:5},
{ formula: '=SoldeN_1("1")+SoldeN_1("2")',value:9},
];
Why don't you just put your data inside an object and map the data inside loop?
There is no need to use eval at all.
const data = {
SoldeN: {
1: 4,
},
SoldeN_1: {
2: 5,
},
};
const soldes = [
{ formula: '=SoldeN("1")', value: 0 },
{ formula: '=SoldeN_1("2")', value: 0 },
{ formula: '=SoldeN("1")+SoldeN_1("2")', value: 0 },
];
const getProperty = string =>
string.match(/\(.*?\)/g).map(x => x.replace(/[(")]/g, ""));
const getObject = string =>
string.match(/[=+](.*?)\(/g).map(x => x.replace(/[=(+]/g, ""));
const output = soldes.map(solde => {
const objs = getObject(solde.formula);
const props = getProperty(solde.formula);
const newVal = objs.reduce((carry, item, idx) => {
carry += data[item][props[idx]];
return carry;
}, solde.value);
return {
...solde,
value: newVal,
};
});
console.log(output);
You can eval the object name.
const SoldeN = { 1:4 };
const getPropertyValue = (obj, prop) => eval(obj)[prop];
console.log(getPropertyValue('SoldeN','1'));
But be cautious as it is risky! If bad code can get into the eval argument, things can happen.
You can make use of javascript eval method to execute the expression.
Logic
Loop through nodes in soldes.
Replace all "=" with empty string. "(" with "[" and ")" with "]".
This will mmake the expression =SoldeN("1")+SoldeN_1("2") to SoldeN["1"]+SoldeN_1["2"].
Evaluating this will give you the expected result.
const SoldeN = {
1: 4,
};
const SoldeN_1 = {
2: 5,
};
const soldes = [
{ formula: '=SoldeN("1")', value: 0 },
{ formula: '=SoldeN_1("2")', value: 0 },
{ formula: '=SoldeN("1")+SoldeN_1("2")', value: 0 },
];
const getValue = (formula) => eval(formula.replaceAll("=", "").replaceAll("(", "[").replaceAll(")", "]"));
const result = soldes.map((item) => ({
formula: item.formula,
value: getValue(item.formula)
}));
console.log(result);
Please Note Error handling is considered as out of scope.
How can I loop through this array:
const counts = [
"900,google.com",
"60,mail.yahoo.com",
"10,mobile.sports.yahoo.com",
"40,sports.yahoo.com",
"300,yahoo.com",
"10,stackoverflow.com",
"20,overflow.com",
"5,com.com",
"2,en.wikipedia.org",
"1,m.wikipedia.org",
"1,mobile.sports",
"1,google.co.uk",
];
taking each value from this array?
const uniqueDomains = [
'google.com',
'com',
'mail.yahoo.com',
'yahoo.com',
'mobile.sports.yahoo.com',
'sports.yahoo.com',
'stackoverflow.com',
'overflow.com',
'com.com',
'en.wikipedia.org',
'wikipedia.org',
'org',
'm.wikipedia.org',
'mobile.sports',
'sports',
'google.co.uk',
'co.uk',
'uk'
]
I need to find out if string from counts array includes string from uniqueDomains array.
Then push it to the empty object as a key value pairs, where value
is going to be the number in the beginning of the each string from counts array.
I tried this code but it give me wrong result in my object's values(since I am looping twice)
I need kind of avoid looping twice, but I am not sure how.
Example com is mentioned 8 time in counts array, which means result should be this {com: 1345}
Here is my code:
const finalObject = {}
uniqueDomains.forEach((dom) => {
counts.forEach((cnt) => {
if (cnt.includes(dom)) {
const num = parseInt(cnt);
sumArr.push(num);
const res = sumArr.reduce((acc, cur) => {
return acc + cur;
});
finalObject[dom] = res;
}
});
});
Theres not really any avoiding looping twice (at least), but you can certainly make your code a bit easieer by first turning the count array into an array of val & domain separately.
const countIdx = counts.map(x => {
const [val,domain] = x.split(",");
return {val:parseInt(val,10), domain}
});
Then its just a case of looping the uniqueDomain array and finding all the domaion which match and summing up the val
const result = uniqueDomains.reduce( (res, d) => {
const count = countIdx.filter(x => x.domain.includes(d)).reduce( (acc,x) => acc + x.val,0);
return {...res, [d]:count}
},{});
Live example follows:
const counts = [
"900,google.com",
"60,mail.yahoo.com",
"10,mobile.sports.yahoo.com",
"40,sports.yahoo.com",
"300,yahoo.com",
"10,stackoverflow.com",
"20,overflow.com",
"5,com.com",
"2,en.wikipedia.org",
"1,m.wikipedia.org",
"1,mobile.sports",
"1,google.co.uk",
];
const uniqueDomains = [
'google.com',
'com',
'mail.yahoo.com',
'yahoo.com',
'mobile.sports.yahoo.com',
'sports.yahoo.com',
'stackoverflow.com',
'overflow.com',
'com.com',
'en.wikipedia.org',
'wikipedia.org',
'org',
'm.wikipedia.org',
'mobile.sports',
'sports',
'google.co.uk',
'co.uk',
'uk'
]
const countIdx = counts.map(x => {
const [val,domain] = x.split(",");
return {val:parseInt(val,10), domain}
});
const result = uniqueDomains.reduce( (res, d) => {
const count = countIdx.filter(x => x.domain.includes(d)).reduce( (acc,x) => acc + x.val,0);
return {...res, [d]:count}
},{});
console.log(result);
Maybe try something like:
let finalObject = {}
uniqueDomains.forEach((dom) => {
finalObject[dom] = 0;
counts.forEach((cnt) => {
if (cnt.includes(dom)) {
finalObject[dom] += parseInt(cnt);
}
});
});
Convert dot notation strings to array objects,
Eg.,
let obj = { 'user-0-address-pincode': 665766, 'user-0-address-city': 'Chennai', 'user-1-address-pincode': 32432, 'user-1-address-city': 'Bangalore'};
// Expectation output will be
{
user: [
{
address: {pincode: 665766, city: 'Chennai'}
},
{
address: {pincode: 32432, city: 'Bangalore'}
}
]
}
Please help me to resolve this problem.
You can use reduce and split methods to create a function that will take your object with keys as paths and then based on those keys create nested structure.
let obj = {
'user-0-address-pincode': 665766,
'user-0-address-city': 'Chennai',
'user-1-address-pincode': 32432,
'user-1-address-city': 'Bangalore'
};
function parse(data) {
return Object.keys(obj).reduce((r, k) => {
k.split('-').reduce((a, e, i, arr) => {
const next = arr[i + 1]
if (!next) return a[e] = data[k]
else return a[e] || (a[e] = (!isNaN(+next) ? [] : {}))
}, r)
return r;
}, {})
}
const result = parse(obj)
console.log(result)
I have a requirement to replace the available keys with the desired keys in an object for which I was trying to execute below code, which later I found out to be incorrect usage of filter for desired output. hence I need help in getting the desired results using es6 array functions.
const columns = Object.keys(someArray).filter((columnName) => {
if (someCheck === "somecheck") {
if (columnName === 'MyName') {
const newcolumnName = `Pranav`;
return newcolumnName;
} else if (columnName === 'YourName') {
const newcolumnName = `Alex`;
return newcolumnName;
}
} else {
return (columnName !== 'sometingelse') ? columnName : '';
}
}
);
Here the someArray is as below:
someArray{
abc:"djfhdjf",
xyz:"ssss",
MyName:"onename",
YourName:"somename",
sometingelse:'somevalue'
}
I am expecting columns to be:
columns{
abc:"djfhdjf",
xyz:"ssss",
Pranav:"onename",
Alex:"somename",
sometingelse:'somevalue'
}
Please suggest how can I achieve the above expected output?
Note: I dont want to use function keyword in callbacks to avoid eslint errors
You could filter the wanted keys for replacement and replace the keys by using a new key and eleting the old one.
const
object = { abc: "djfhdjf", xyz: "ssss", MyName: "onename", YourName: "somename", sometingelse: 'somevalue' },
replacements = { MyName: 'Pranav', YourName: 'Alex', sometingelse: '' };
Object
.keys(object)
.filter(k => k in replacements)
.forEach(k => {
object[replacements[k]] = object[k];
delete object[k];
});
console.log(object);
For generating an object, you could map new objects and assign them to a single object.
const
object = { abc: "djfhdjf", xyz: "ssss", MyName: "onename", YourName: "somename", sometingelse: 'somevalue' },
replacements = { MyName: 'Pranav', YourName: 'Alex', sometingelse: '' },
result = Object.assign(...Object
.entries(object)
.map(([k, v]) => ({ [k in replacements ? replacements[k] : k]: v }))
);
console.log(result);
const obj = {
abc: 'djfhdjf',
xyz: 'ssss',
MyName: 'onename',
YourName: 'somename',
sometingelse: 'somevalue'
};
const newObj = Object.keys(obj).reduce((acc, key) => {
if (key === 'MyName') {
acc.newMyName = obj[key];
} else if (key === 'YourName') {
acc.newYourName = obj[key];
} else {
acc[key] = obj[key];
}
return acc;
}, {});
console.log('newObj = ', newObj);
Here is my approach, a bit long solution, but its on purpose so you can see how to do it simple without too much abstraction:
const someArray = {
abc:"djfhdjf",
xyz:"ssss",
MyName:"onename",
YourName:"somename",
sometingelse:'somevalue'
}
let foo = Object.keys(someArray).map(key => {
if(key === 'MyName') {
return 'Alex'
} else if(key === 'YourName') {
key = 'Pranav'
}
return key;
})
let bar = Object.entries(someArray).map((el, i) => {
el[0] = res[i];
return el;
})
let baz = r.reduce((acc, el)=>{
acc[`${el[0]}`] = el[1];
return acc;
},{})
console.log(baz);
You could use .reduce like so. It uses a similar idea that Nina proposed by using an object to hold your replacements. Here I have used the spread syntax to add the changed key to the accumulated object, along with it's associated value.
const someArray = {abc: "djfhdjf", xyz: "ssss", MyName: "onename", YourName: "somename", sometingelse: 'somevalue'},
toUse = {MyName: "Pranav", YourName: "Alex"}, // define the keys you want to change and what they should change to
res = Object.keys(someArray).reduce((acc, key) =>
({...acc, [key in toUse ? toUse[key] : key]:someArray[key]})
, {});
console.log(res);
I am running a reduce on the keys of some array starting with an empty object. The ...acc spreads out all the properties in the reduced object. ...{ [keysMap[key] || key]: obj[key] } checks if the current key is present in keysMap.If it is present,it uses that key (keysMap[key]) otherwise it just uses the keys of the existing object.(|| key).Hope that makes sense
const renameKeys = (keysMap, obj) =>
Object.keys(obj).reduce(
(acc, key) => ({
...acc,
...{ [keysMap[key] || key]: obj[key] }
}),
{}
)
const columns = renameKeys({'MyName':'Pranav','YourName':'Alex'},someArray)
I have a very weird issue in my lodash codes
I have something like
data = {
'id':'123',
'employee_name': 'John',
'employee_type': 'new'
}
var newObj = _.mapValues(data, function (value, key) {
var t = _.camelCase(key);
console.log(t) -> shows employeeName and employeeType
return _.camelCase(key);
});
I was expecting my newObj will become
data = {
'id':'123',
'employeeName': 'John',
'employeeType': 'new'
}
after I ran the codes above, it still stays the same as it was like
data = {
'id':'123',
'employee_name': 'John',
'employee_type': 'new'
}
This is super weird and I'm not sure what went wrong. Can someone help me about this? Thanks a lot!
replacing snake_case or kebab-case to camelCase only for string (ES6+):
const snakeToCamel = str =>
str.toLowerCase().replace(/([-_][a-z])/g, group =>
group
.toUpperCase()
.replace('-', '')
.replace('_', '')
);
result:
console.log(snakeToCamel('TO_CAMEL')) //toCamel
console.log(snakeToCamel('to_camel')) //toCamel
console.log(snakeToCamel('TO-CAMEL')) //toCamel
console.log(snakeToCamel('to-camel')) //toCamel
Use _.mapKeys() instead of _.mapValues():
var data = {
'id': '123',
'employee_name': 'John',
'employee_type': 'new'
};
var newObj = _.mapKeys(data, (value, key) => _.camelCase(key));
console.log('newObj: ', newObj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script>
If you need to ignore the redundant value param, you can use _.rearg() on _.camelCase() to generate a function that takes the 2nd param (the key) instead of the 1st param (the value).
var data = {
'id': '123',
'employee_name': 'John',
'employee_type': 'new'
};
var newObj = _.mapKeys(data, _.rearg(_.camelCase, 1));
console.log('newObj: ', newObj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script>
You can also easily create your own function for that:
function camelCase(obj) {
var newObj = {};
for (d in obj) {
if (obj.hasOwnProperty(d)) {
newObj[d.replace(/(\_\w)/g, function(k) {
return k[1].toUpperCase();
})] = obj[d];
}
}
return newObj;
}
var data = {
'id': '123',
'employee_name': 'John',
'employee_type': 'new'
}
console.log(camelCase(data));
Here's how to do it in native Javascript...
let data = {
'id':'123',
'employee_name': 'John',
'employee_type': 'new'
}
// #1 simple function which converts a string from snake case to camel case ...
const snakeToCamel = s => s.replace(/(_\w)/g, k => k[1].toUpperCase())
// #2 create new data object with camelCase keys...
data = Object.entries(data).reduce((x,[k,v]) => (x[snakeToCamel(k)]=v) && x, {})
console.log(data)
For my use case I needed (or wanted) a function that would handle any arbitrary json object, including nested objects, arrays, etc. Came up with this, seems to be working so far:
const fromSnakeToCamel = (data) => {
if (_.isArray(data)) {
return _.map(data, fromSnakeToCamel);
}
if (_.isObject(data)) {
return _(data)
.mapKeys((v, k) => _.camelCase(k))
.mapValues((v, k) => fromSnakeToCamel(v))
.value();
}
return data;
}
Note that if it's not an array or an object, I just return the data because I only actually want to convert keys. Anyway, hope this helps someone
These are all good answers, but they did not fit what I needed. I like Ashish's answer because it handles nested objects, but what if there are underscores in the data that you want? So, here is a varient on Bambam's answer to make it recursive, because lodash can sometimes be a pain.
function toCamelCase (obj) {
let rtn = obj
if(!rtn) {
return rtn
} else if (typeof (obj) === 'object') {
if (obj instanceof Array) {
rtn = obj.map(toCamelCase)
} else {
rtn = {}
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
const newKey = key.replace(/(_\w)/g, k => k[1].toUpperCase())
rtn[newKey] = toCamelCase(obj[key])
}
}
}
}
return rtn
}
TypeScript
As always, nobody asked for typescript version, but here it is, please don't beat me ^-^.
Without _, No RegExp
I split functions in two modules but you can keep them outside with proper naming
I put never to mark out that the type is actually correct since TS doesn't always know if it is.
You still can use _ and get code shorter but I wanted to breakdown the process.
module CaseTransform {
export type Snake = Lowercase<`${string}_${string}`>
export type Camel = Capitalize<string> | `${Capitalize<string>}${Capitalize<string>}`
export type SnakeToCamel<S extends string> = S extends `${infer Start}_${infer Rest}` ? `${Start}${Capitalize<SnakeToCamel<Rest>>}` : S
type SnakeToCamel__TEST__ = SnakeToCamel<"my_account_profile"> // myAccountProfile
export function capitalize<S extends string>(string: S): Capitalize<S> {
if (string.length === 0) return "" as never
return (string[0].toUpperCase() + string.slice(1)) as never
}
export function snakeToCamel<S extends string>(string: S): SnakeToCamel<S> {
const [start, ...rest] = string.split("_")
return (start + rest.map(capitalize)) as never
}
const snakeToCamel__TEST__ = snakeToCamel("ASD_asd_asdad_")
}
module ObjectTransform {
export function snakeToCamel<O extends object, K extends keyof O>(object: O): { [P in K as (P extends CaseTransform.Snake ? CaseTransform.SnakeToCamel<P> : P)]: O[P] } {
return Object
.entries(object)
.reduce((result, [key, value]) => ({
...result,
[CaseTransform.snakeToCamel(key)]: value
}), {}) as never
}
}
const sample = {
id: 123,
employee_name: "John",
employee_type: "new",
camelCase: "123",
PascalCase: "123"
}
const __TEST__ = ObjectTransform.snakeToCamel(sample)
Note
If you want all characters (even abbreviations) to be in lowercase, put .toLowercase() after string AND change SnakeToCamel type to
type SnakeToCamel<S extends string> = S extends `${infer Start}_${infer Rest}` ? `${Lowercase<Start>}${Capitalize<SnakeToCamel<Rest>>}` : Lowercase<S>
Easy!
Typings Result
JavaScript Playground
function capitalize(string) {
if (string.length === 0) return ""
return (string[0].toUpperCase() + string.slice(1))
}
function snakeToCamel(string){
const [start, ...rest] = string.split("_")
return (start + rest.map(capitalize).join(""))
}
const snakeToCamel__TEST__ = snakeToCamel("ASD_asd_asdad_")
console.log(snakeToCamel__TEST__)
function objectKeysSnakeToCamel(object) {
return Object
.entries(object)
.reduce((result, [key, value]) => ({
...result,
[snakeToCamel(key)]: value
}), {})
}
const sample = {
id: 123,
employee_name: "John",
employee_type: "new",
camelCase: "123",
PascalCase: "123"
}
const __TEST__ = objectKeysSnakeToCamel(sample)
console.log(__TEST__)
Here is another answer using simple for loop.
var data = {
'id': '123',
'employee_name': 'John',
'employee_type': 'new'
};
var output = {}
for (var key in data) {
output[_.camelCase(key)] = data[key];
}
Try this it will definitely work as expected.
const helpers = {};
helpers.camelize = function(str) {
return str.trim().replace(/[A-Z]+/g, (letter, index) => {
return index == 0 ? letter.toLowerCase() : '_' + letter.toLowerCase();
}).replace(/(.(\_|-|\s)+.)/g, function(subStr) {
return subStr[0]+(subStr[subStr.length-1].toUpperCase());
});
}
helpers.camelizeKeys = function(data) {
const result = {};
for (const [key, val] of Object.entries(data)) {
result[helpers.camelize(key)] = val;
}
return result;
}
helpers.camelizeNestedKeys = function(dataObj) {
return JSON.parse(JSON.stringify(dataObj).trim().replace(/("\w+":)/g, function(keys) {
return keys.replace(/[A-Z]+/g, (letter, index) => {
return index == 0 ? letter.toLowerCase() : '_' + letter.toLowerCase();
}).replace(/(.(\_|-|\s)+.)/g, function(subStr) {
return subStr[0]+(subStr[subStr.length-1].toUpperCase());
});
}));
}
const data = {
'id':'123',
'employee_name': 'John',
'employee_type': 'new'
};
const nestedData = {
'id':'123',
'employee_name': 'John',
'employee_type': 'new',
'exployee_projects': [
{"project_name": "test1", "project_year": 2004},
{"project_name": "test2", "project_year": 2004}
]
};
// Few camelize Examples
const str1 = "banana_orange_apple_mango";
const str2 = "banana-orange-apple-mango";
const str3 = "banana orange apple mango";
const str4 = "BANANA Orange APPLE-mango";
const str5 = "banana 5orange apple #mango";
const str6 = "banana__orange-_apple5-#mango";
console.log(helpers.camelize(str1));
console.log(helpers.camelize(str2));
console.log(helpers.camelize(str3));
console.log(helpers.camelize(str4));
console.log(helpers.camelize(str5));
console.log(helpers.camelize(str6));
console.log("=============================");
// camelize object keys
console.log(helpers.camelizeKeys(data));
console.log("=============================");
// camelize nested object keys
console.log(helpers.camelizeNestedKeys(nestedData));
If you want to convert the nested object, then using lodash can be a bit painful.
I tried using regex, JSON.parse & JSON.stringify
and here is the code for the same
below code returns the new object that is having camel case instead of snake case
//input
var data = {
'id': '123',
'employee_name': 'John',
'employee_type': {'new_name': 'foo'}
};
JSON.parse(JSON.stringify(data).replace(
/(_\w)\w+":/g,
match => match[1].toUpperCase() + match.substring(2)
));
{
'id': '123',
'employeeName': 'John',
'employeeType': {'newName': 'foo'}
}
Based on Abbos Tajimov's answer (and Ali's comment), we could also take advantage of the arguments passed down to the inline function.
const snakeToCamel = str => {
if (!(/[_-]/).test(str)) return str
return str.toLowerCase()
.replace(/([-_])([a-z])/g, (_match, _p1, p2) => p2.toUpperCase())
}
camelCase(str) {
return str
.toLowerCase()
.replace(/([-_][a-z])/g, (ltr) => ltr.toUpperCase())
.replace(/[^a-zA-Z]/g, '')
}
another way
_(data)
.keys()
.map(_.camelCase)
.zipObject(_.values(data))
.value()
I really like Mardok's version with nested objects, only issue is that it converts "null" to {}
here mine:
import _ from 'lodash';
export const toCamelCase: any = (obj: any) => {
let rtn = obj
if (typeof obj === 'object') {
if (obj instanceof Array) {
rtn = obj.map(toCamelCase)
}
else if (_.isEmpty(obj)) {
rtn = null
} else {
rtn = {}
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
const newKey = key.replace(/(_\w)/g, k => k[1].toUpperCase())
rtn[newKey] = toCamelCase(obj[key])
}
}
}
}
return rtn
}
Creates camelized object recursively.
function camelCase(obj) {
const newObj = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const value = obj[key];
const keyCamel = key.replace(/(\_\w)/g, (match) => match[1].toUpperCase());
const isRecursive = typeof value === 'object';
newObj[keyCamel] = isRecursive ? camelCase(value) : value;
}
}
return newObj;
}
let data = {
id: '123',
employee_name: 'John',
inner: {
employee_type: 'new'
},
}
camelCase(data);
Found in typeorm repo https://github.com/typeorm/typeorm/blob/master/src/util/StringUtils.ts#L8
export function camelCase(str: string, firstCapital: boolean = false): string {
return str.replace(
/^([A-Z])|[\s-_](\w)/g,
function (match, p1, p2, offset) {
if (firstCapital === true && offset === 0) return p1
if (p2) return p2.toUpperCase()
return p1.toLowerCase()
},
)
}
Use npm json-case-handler which will allow you to do this in one line.
It can convert any nested objects
For your case, you can do this :
const jcc = require('json-case-convertor')
const snakeCasedJson = jcc.snakeCaseKeys(yourjsonData)
Just pass the value to input and the result will be camelcase:
const snakeToCamel = input =>
console.log(
input.slice(0, input.indexOf('_')).toLowerCase() +
input[input.indexOf('_') + 1].toUpperCase() +
input.slice(input.indexOf('_') + 2)
);
const inputs = [
'underscore_case',
'first_name',
'Some_Variable',
'calculate_AGE',
'delayed_departure',
'Hello_you',
'hAI_i',
];
for (let input of inputs) {
snakeToCamel(input);
}
This function will recursively convert all snake case keys in the object to camelCase. Including objects within arrays and object within objects.
const convertSnakeCaseToCamelCase = (obj) => {
let newObj = {};
if (typeof(obj) !== 'object') {
return obj;
} else if (Array.isArray(obj)) {
newObj = [];
}
for (const key in obj) {
const childObj = convertSnakeCaseToCamelCase(obj[key]);
if (Array.isArray(obj)) {
newObj.push(childObj);
} else {
const newKey = key.replace(/(\_\w)/g, (k) => k[1].toUpperCase());
newObj[newKey] = childObj;
}
}
return newObj;
};