简体   繁体   English

如何在我的应用程序中将蛇壳转换为骆驼壳

[英]How to convert snake case to camelcase in my app

I have a very weird issue in my lodash codes我的 lodash 代码中有一个非常奇怪的问题

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我期待我的 newObj 会变成

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!非常感谢!

Use _.mapKeys() instead of _.mapValues() :使用_.mapKeys()而不是_.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 ).如果您需要忽略冗余value参数,您可以使用_.rearg()上的_.camelCase()来生成一个函数,该函数采用第二个参数( key )而不是第一个参数( 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>

snake-case to camelCase only for string (ES6+):仅适用于字符串(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

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...这是在本机 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:对于我的用例,我需要(或想要)一个可以处理任意 json 对象的函数,包括嵌套对象、数组等。想出了这个,到目前为止似乎正在工作:

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?我喜欢 Ashish 的回答,因为它处理嵌套对象,但是如果您想要的数据中有下划线怎么办? So, here is a varient on Bambam's answer to make it recursive, because lodash can sometimes be a pain.因此,这里是 Bambam 的答案的变体,以使其递归,因为 lodash 有时会很痛苦。

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
}

Here is another answer using simple for loop.这是另一个使用简单 for 循环的答案。

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(/[AZ]+/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(/[AZ]+/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.如果你想转换嵌套对象,那么使用 lodash 可能会有点痛苦。

I tried using regex, JSON.parse & JSON.stringify and here is the code for the same我尝试使用正则表达式、JSON.parse 和 JSON.stringify,这是相同的代码

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 .根据 Abbos Tajimov 的回答(和 Ali 的评论),我们还可以利用传递给内联函数的参数

const snakeToCamel = str => {
  if (!(/[_-]/).test(str)) return str

  return str.toLowerCase()
    .replace(/([-_])([a-z])/g, (_match, _p1, p2) => p2.toUpperCase())
}

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 {}我真的很喜欢带有嵌套对象的 Mardok 版本,唯一的问题是它将“null”转换为 {}

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在 typeorm 存储库中找到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.使用 npm json-case-handler这将允许您在一行中执行此操作。

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 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); }

` `

  camelCase(str) {
    return str
      .toLowerCase()
      .replace(/([-_][a-z])/g, (ltr) => ltr.toUpperCase())
      .replace(/[^a-zA-Z]/g, '')
  }

This function will recursively convert all snake case keys in the object to camelCase.这个函数会递归地将对象中的所有snake case键转换为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;
};

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

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