Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert javascript object camelCase keys to underscore_case

I want to be able to pass any javascript object containing camelCase keys through a method and return an object with underscore_case keys, mapped to the same values.

So, I have this:

var camelCased = {firstName: 'Jon', lastName: 'Smith'}

And I want a method to output this:

{first_name: 'Jon', last_name: 'Jon'}

What's the fastest way to write a method that takes any object with any number of key/value pairs and outputs the underscore_cased version of that object?

like image 223
JMac Avatar asked Jun 21 '15 23:06

JMac


People also ask

Can I use snake case in JavaScript?

Snake case (also referred to as underscore case) is when all the letters of the word are lower case but delimited by an underscore. We seldom use the snake case coding convention in C-style languages like Java, JavaScript, and TypeScript.

Can objects have same keys JavaScript?

No, JavaScript objects cannot have duplicate keys. The keys must all be unique.


3 Answers

Here's your function to convert camelCase to underscored text (see the jsfiddle):

function camelToUnderscore(key) {
    return key.replace( /([A-Z])/g, "_$1").toLowerCase();
}

console.log(camelToUnderscore('helloWorldWhatsUp'));

Then you can just loop (see the other jsfiddle):

var original = {
    whatsUp: 'you',
    myName: 'is Bob'
},
    newObject = {};

function camelToUnderscore(key) {
    return key.replace( /([A-Z])/g, "_$1" ).toLowerCase();
}

for(var camel in original) {
    newObject[camelToUnderscore(camel)] = original[camel];
}

console.log(newObject);
like image 194
Josh Beam Avatar answered Oct 10 '22 22:10

Josh Beam


Marcos Dimitrio posted above with his conversion function, which works but is not a pure function as it changes the original object passed in, which may be an undesireable side effect. Below returns a new object that doesn't modify the original.

export function camelCaseKeysToSnake(obj){
  if (typeof(obj) != "object") return obj;
  let newObj = {...obj}
  for(var oldName in newObj){

      // Camel to underscore
      let newName = oldName.replace(/([A-Z])/g, function($1){return "_"+$1.toLowerCase();});

      // Only process if names are different
      if (newName != oldName) {
          // Check for the old property name to avoid a ReferenceError in strict mode.
          if (newObj.hasOwnProperty(oldName)) {
              newObj[newName] = newObj[oldName];
              delete newObj[oldName];
          }
      }

      // Recursion
      if (typeof(newObj[newName]) == "object") {
          newObj[newName] = camelCaseKeysToSnake(newObj[newName]);
      }
  }
  return newObj;
} 
like image 41
jbrian24 Avatar answered Oct 10 '22 23:10

jbrian24


es6 node solution below. to use, require this file, then pass object you want converted into the function and it will return the camelcased / snakecased copy of the object.

const snakecase = require('lodash.snakecase');

const traverseObj = (obj) => {
  const traverseArr = (arr) => {
    arr.forEach((v) => {
      if (v) {
        if (v.constructor === Object) {
          traverseObj(v);
        } else if (v.constructor === Array) {
          traverseArr(v);
        }
      }
    });
  };

  Object.keys(obj).forEach((k) => {
    if (obj[k]) {
      if (obj[k].constructor === Object) {
        traverseObj(obj[k]);
      } else if (obj[k].constructor === Array) {
        traverseArr(obj[k]);
      }
    }

    const sck = snakecase(k);
    if (sck !== k) {
      obj[sck] = obj[k];
      delete obj[k];
    }
  });
};

module.exports = (o) => {
  if (!o || o.constructor !== Object) return o;

  const obj = Object.assign({}, o);

  traverseObj(obj);

  return obj;
};
like image 35
Bryan Schoen Avatar answered Oct 10 '22 23:10

Bryan Schoen