javascript - Rename Object Keys from Snake Case to Camel Case Recursively Without Using Lodash - Stack Overflow

How to recursively convert object keys from snake case to camel case using plain javascript without rel

How to recursively convert object keys from snake case to camel case using plain javascript without relying on external libraries such as Lodash. Below is an attempt that only works for first level of the object. What's the best way to do this?

const obj = {
  key_first: 'firstVal',
  key_second: 'secondVal',
  key_third: null,
  nested_obj: {
    nested_one: 'nested 1 value',
    nested_two: 'nested 2 value'
  },
  nested_arr: [{
    nested_obj_one: 'nested obj val 1'
  }, {
    nested_obj_two: 'nested obj val 2'
  }, {
    level_3_nested: [{
      level_3_key: 'level 3 value',
      level_3_another_key: 'another level 3 value'
    }]
  }]
};
const renameKeys = obj => Object
  .entries(obj)
  .reduce((acc, [key, val]) => {
    const modifiedKey = key.replace(/_([a-z])/g, g =>  g[1].toUpperCase());
    return ({
      ...acc,
      ...{ [modifiedKey]: val },
    });
  }, {});
console.log(renameKeys(obj));

Update: Added key with value of null.

How to recursively convert object keys from snake case to camel case using plain javascript without relying on external libraries such as Lodash. Below is an attempt that only works for first level of the object. What's the best way to do this?

const obj = {
  key_first: 'firstVal',
  key_second: 'secondVal',
  key_third: null,
  nested_obj: {
    nested_one: 'nested 1 value',
    nested_two: 'nested 2 value'
  },
  nested_arr: [{
    nested_obj_one: 'nested obj val 1'
  }, {
    nested_obj_two: 'nested obj val 2'
  }, {
    level_3_nested: [{
      level_3_key: 'level 3 value',
      level_3_another_key: 'another level 3 value'
    }]
  }]
};
const renameKeys = obj => Object
  .entries(obj)
  .reduce((acc, [key, val]) => {
    const modifiedKey = key.replace(/_([a-z])/g, g =>  g[1].toUpperCase());
    return ({
      ...acc,
      ...{ [modifiedKey]: val },
    });
  }, {});
console.log(renameKeys(obj));

Update: Added key with value of null.

Share Improve this question edited Oct 6, 2019 at 15:02 Steve asked Oct 6, 2019 at 12:58 SteveSteve 5,19414 gold badges51 silver badges65 bronze badges 1
  • Hi, Try this stackoverflow./a/73220750/11888809 , you can do this in one line of code – SWIK Commented Aug 3, 2022 at 11:22
Add a ment  | 

4 Answers 4

Reset to default 4

I'd .map the Object.entries, replacing the key in the entry, while recursively calling renamekeys on the value, and pass the whole array entry to Object.fromEntries to turn it back into an object.

Since you have nested arrays too, not just nested objects. you'll have to test for them and .map each item via renameKeys if found.

You also probably want to tweak the regex so that all underscores get replaced, not just those followed by alphabetical characters:

const obj = {
  key_first: 'firstVal',
  key_second: 'secondVal',
  nested_obj: {
    nested_one: 'nested 1 value',
    nested_two: 'nested 2 value'
  },
  nested_arr: [{
    nested_obj_one: 'nested obj val 1'
  }, {
    nested_obj_two: 'nested obj val 2'
  }, {
    level_3_nested: [{
      level_3_key: 'level 3 value',
      level_3_another_key: 'another level 3 value'
    }]
  }]
};

const processVal = val => (
  typeof val !== 'object'
  ? val
  : Array.isArray(val)
    ? val.map(renameKeys)
    : renameKeys(val)
);
const renameKeys = obj => Object.fromEntries(
  Object.entries(obj)
    .map(([key, val]) => [
      key.replace(/_(.)/g, g =>  g[1].toUpperCase()),
      processVal(val)
    ])
);
console.log(renameKeys(obj));

To permit null values as well:

const obj = {
  key_first: 'firstVal',
  key_second: 'secondVal',
  nested_obj: {
    nested_one: 'nested 1 value',
    nested_two: 'nested 2 value'
  },
  nested_arr: [{
    nested_obj_one: 'nested obj val 1'
  }, {
    nested_obj_two: 'nested obj val 2'
  }, {
    level_3_nested: [{
      level_3_key: 'level 3 value',
      level_3_another_key: 'another level 3 value'
    }]
  }]
};

const processVal = val => (
  (typeof val !== 'object' || val === null)
  ? val
  : Array.isArray(val)
    ? val.map(renameKeys)
    : renameKeys(val)
);
const renameKeys = obj => Object.fromEntries(
  Object.entries(obj)
    .map(([key, val]) => [
      key.replace(/_(.)/g, g =>  g[1].toUpperCase()),
      processVal(val)
    ])
);
console.log(renameKeys(obj));

If the arrays can be on the first level, then use val.map(processVal) in processVal, and first call processVal instead of renameKeys:

const obj = {
  simple_arr: ['a1', 'b1', 'c1'],
  key_first: 'firstVal',
  key_second: 'secondVal',
  nested_obj: {
    nested_one: 'nested 1 value',
    nested_two: 'nested 2 value'
  },
  nested_arr: [{
    nested_obj_one: 'nested obj val 1'
  }, {
    nested_obj_two: 'nested obj val 2'
  }, {
    level_3_nested: [{
      level_3_key: 'level 3 value',
      level_3_another_key: 'another level 3 value'
    }]
  }]
};

const processVal = val => (
  (typeof val !== 'object' || val === null)
  ? val
  : Array.isArray(val)
    ? val.map(processVal)
    : renameKeys(val)
);
const renameKeys = obj => Object.fromEntries(
  Object.entries(obj)
    .map(([key, val]) => [
      key.replace(/_(.)/g, g =>  g[1].toUpperCase()),
      processVal(val)
    ])
);
console.log(processVal(obj));

Add recursive call for nested object

const renameKeys = obj => Object
  .entries(obj)
  .reduce((acc, [key, val]) => {
    const modifiedKey = key.replace(/_([a-z])/g, g =>  g[1].toUpperCase());
    const modifiedVal = typeof val === 'object' && val !== null ? 
        renameKeys(val) : val;
    return ({
      ...acc,
      ...{ [modifiedKey]: modifiedVal },
    });
  }, {});

You can use for..in something like this

const obj = {key_first: 'firstVal',key_second: 'secondVal',nested_obj: {nested_one: 'nested 1 value',nested_two: 'nested 2 value'},nested_arr: [{nested_obj_one: 'nested obj val 1'}, {nested_obj_two: 'nested obj val 2'}, {level_3_nested: [{level_3_key: 'level 3 value',level_3_another_key: 'another level 3 value'}]}]};

let keyChanger = (obj) => {
  for (let key in obj) {
    if (typeof obj[key] === 'object') {
      if (Array.isArray(obj[key])) {
        obj[key].map(v => keyChanger(v))
      } else {
        keyChanger(obj[key])
      }
    }
    const modifiedKey = key.replace(/_([a-z])/g, g => g[1].toUpperCase());
    obj[modifiedKey] = obj[key]
    delete obj[key]
  }
  return obj
}

console.log(keyChanger(obj))

I think this method of camelizing nested object keys will save lot of iterations.

const camelizeNestedKeys = function(dataObj) {
    return JSON.parse(JSON.stringify(dataObj).trim().replace(/("\w+":)/g, function(keys) {
        return keys.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}
    ]
};

console.log(camelizeNestedKeys(data));

console.log(camelizeNestedKeys(nestedData));

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744892541a4599501.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信