简体   繁体   English

将 javascript object camelCase 键转换为 underscore_case

[英]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.我希望能够通过一个方法传递包含驼峰式键的任何 javascript object 并返回一个带有 underscore_case 键的 object,映射到相同的值。

So, I have this:所以,我有这个:

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

And I want a method to output this:我想要一个方法 output 这个:

{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?编写一个接受任何 object 和任意数量的键/值对并输出该 object 的 underscore_cased 版本的方法的最快方法是什么?

Here's your function to convert camelCase to underscored text (see the jsfiddle ):这是将驼峰大小写转换为下划线文本的函数(请参阅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 ):然后你可以循环(参见其他 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);

If you have an object with children objects, you can use recursion and change all properties:如果您有一个带有子对象的对象,您可以使用递归并更改所有属性:

function camelCaseKeysToUnderscore(obj){
    if (typeof(obj) != "object") return obj;

    for(var oldName in obj){

        // Camel to underscore
        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 (obj.hasOwnProperty(oldName)) {
                obj[newName] = obj[oldName];
                delete obj[oldName];
            }
        }

        // Recursion
        if (typeof(obj[newName]) == "object") {
            obj[newName] = camelCaseKeysToUnderscore(obj[newName]);
        }

    }
    return obj;
}

So, with an object like this:因此,对于这样的对象:

var obj = {
    userId: 20,
    userName: "John",
    subItem: {
        paramOne: "test",
        paramTwo: false
    }
}

newobj = camelCaseKeysToUnderscore(obj);

You'll get:你会得到:

{
    user_id: 20,
    user_name: "John",
    sub_item: {
        param_one: "test",
        param_two: false
    }
}

es6 node solution below. es6节点解决方案如下。 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;
};

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. Marcos Dimitrio 在上面发布了他的转换函数,该函数有效但不是纯函数,因为它更改了传入的原始对象,这可能是一个不受欢迎的副作用。 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;
} 

Came across this exact problem when working between JS & python/ruby objects.在 JS 和 python/ruby 对象之间工作时遇到了这个确切的问题。 I noticed the accepted solution is using for in which will throw eslint error messages at you ref: https://github.com/airbnb/javascript/issues/851 which alludes to rule 11.1 re: use of pure functions rather than side effects ref: https://github.com/airbnb/javascript#iterators--nope我注意到接受的解决方案正在使用for in which will throw eslint error messages at you ref: https://github.com/airbnb/javascript/issues/851这暗示了规则 11.1 re:使用纯函数而不是副作用 ref : https://github.com/airbnb/javascript#iterators--nope

To that end, figured i'd share the below which passed the said rules.为此,我想我会分享以下通过上述规则的内容。

import { snakeCase } from 'lodash'; // or use the regex in the accepted answer

camelCase = obj => {
  const camelCaseObj = {};
  for (const key of Object.keys(obj)){
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
     camelCaseObj[snakeCase(key)] = obj[key];
    }
  }

  return camelCaseObj;
};

this library does exactly that: case-converter It converts snake_case to camelCase and vice versa这个库就是这样做的: case-converter它将snake_case 转换为camelCase,反之亦然

  const caseConverter = require('case-converter')

  const snakeCase = {
    an_object: {
      nested_string: 'nested content',
      nested_array: [{ an_object: 'something' }]
    },
    an_array: [
      { zero_index: 0 },
      { one_index: 1 }
    ]
  }

  const camelCase = caseConverter.toCamelCase(snakeCase);

  console.log(camelCase)
  /*
    {
      anObject: {
        nestedString: 'nested content',
        nestedArray: [{ anObject: 'something' }]
      },
      anArray: [
        { zeroIndex: 0 },
        { oneIndex: 1 }
      ]
    }
  */

following what's suggested above, case-converter library is deprectaed, use snakecase-keys instead - https://github.com/bendrucker/snakecase-keys按照上面的建议,不推荐使用case-converter库,请改用snakecase-keys - https://github.com/bendrucker/snakecase-keys

supports also nested objects & exclusions.还支持嵌套对象和排除。

Any of the above snakeCase functions can be used in a reduce function as well:上述任何 snakeCase 函数也可以在 reduce function 中使用:

const snakeCase = [lodash / case-converter / homebrew]

const snakeCasedObject = Object.keys(obj).reduce((result, key) => ({
      ...result,
      [snakeCase(key)]: obj[key],
    }), {})

jsfiddle提琴手

//This function will rename one property to another in place
Object.prototype.renameProperty = function (oldName, newName) {
     // Do nothing if the names are the same
     if (oldName == newName) {
         return this;
     }
    // Check for the old property name to avoid a ReferenceError in strict mode.
    if (this.hasOwnProperty(oldName)) {
        this[newName] = this[oldName];
        delete this[oldName];
    }
    return this;
};

//rename this to something like camelCase to snakeCase
function doStuff(object) {
    for (var property in object) {
        if (object.hasOwnProperty(property)) {
            var r = property.replace(/([A-Z])/, function(v) { return '_' + v.toLowerCase(); });
            console.log(object);
            object.renameProperty(property, r);
            console.log(object);
        }
    }
}

//example object
var camelCased = {firstName: 'Jon', lastName: 'Smith'};
doStuff(camelCased);

Note: remember to remove any and all console.log s as they aren't needed for production code注意:记住删除任何和所有的console.log s,因为它们不是生产代码所需要的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM