简体   繁体   English

递归地将 object 字段从蛇形大小写转换为驼峰大小写

[英]Recursively convert an object fields from snake case to camelCase

I had an object like this (fields in snake_case )我有一个像这样的 object( snake_case中的字段)

const obj = {
  vt_core_random: {
    user_details: {
      first_name: "xyz",
      last_name: "abc",
      groups: [
        {
          id: 1,
          group_type: "EXT"
        },
        {
          id: 2,
          group_type: "INT"
        }
      ],
      address_type: {
        city_name: "nashik",
        state: {
          code_name: "MH",
          name: "Maharashtra"
        }
      }
    }
  }
};

I want to recursily convert its fields to camelCase , so the expected output is given below我想递归地将其字段转换为camelCase ,因此下面给出了预期的 output

const obj = {
  vtCoreRandom: {
    userDetails: {
      firstName: "xyz",
      lastName: "abc",
      groups: [
        {
          id: 1,
          groupType: "EXT"
        },
        {
          id: 2,
          groupType: "INT"
        }
      ],
      addressType: {
        cityName: "LMN",
        state: {
          codeName: "KOP",
          name: "PSQ"
        }
      }
    }
  }
};

I tried using mapKeys() but I just can't wrap my head around the recursive part of this.我尝试使用 mapKeys() 但我无法理解其中的递归部分。 any help is highly appreciated.非常感谢任何帮助。 Also I have the ability to use lodash if it makes the process any simpler如果它使过程更简单,我也有能力使用lodash

You can use lodash's _.transform() to create a recursive function that iterates the keys and converts them camel case with _.camelCase() .您可以使用 lodash 的_.transform()创建一个递归函数,该函数迭代键并使用_.camelCase()将它们转换为驼峰式大小写。 Transform can also handle arrays, is the iterated object ( target) is an array, we don't need to change the keys. Transform 也可以处理数组,被迭代的对象( target)是一个数组,我们不需要改变键。

 const camelize = obj => _.transform(obj, (acc, value, key, target) => { const camelKey = _.isArray(target) ? key : _.camelCase(key); acc[camelKey] = _.isObject(value) ? camelize(value) : value; }); const obj = {"vt_core_random":{"user_details":{"first_name":"xyz","last_name":"abc","groups":[{"id":1,"group_type":"EXT"},{"id":2,"group_type":"INT"}],"address_type":{"city_name":"nashik","state":{"code_name":"MH","name":"Maharashtra"}}}}}; const result = camelize(obj); console.log(result);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

You can try something like this:你可以尝试这样的事情:

 const obj = { vt_core_random: { user_details: { first_name: "xyz", last_name: "abc", groups: [ { id: 1, group_type: "EXT" }, { id: 2, group_type: "INT" } ], address_type: { city_name: "nashik", state: { code_name: "MH", name: "Maharashtra" } } } } }; const toCamel = (str) => { return str.replace(/([-_][az])/ig, ($1) => { return $1.toUpperCase() .replace('-', '') .replace('_', ''); }); }; const isObject = function (obj) { return obj === Object(obj) && !Array.isArray(obj) && typeof obj !== 'function'; }; const keysToCamel = function (obj) { if (isObject(obj)) { const n = {}; Object.keys(obj) .forEach((k) => { n[toCamel(k)] = keysToCamel(obj[k]); }); return n; } else if (Array.isArray(obj)) { return obj.map((i) => { return keysToCamel(i); }); } return obj; }; console.log(keysToCamel(obj));

For all the guys using lodash I have manipulated the accepted answer since lodash already includes the utility functions like isArray isObject camelCase对于所有使用 lodash 的人,我已经修改了已接受的答案,因为 lodash 已经包含了实用函数,如isArray isObject camelCase

So the code reduces to this.所以代码简化为这个。 :) :)

function keysToCamel(obj) {
  if (isPlainObject(obj)) {
    const n = {};
    Object.keys(obj).forEach(k => (n[camelCase(k)] = keysToCamel(obj[k])));
    return n;
  } else if (isArray(obj)) obj.map(i => keysToCamel(i));
  return obj;
}
const obj = {
  vt_core_random: {
    user_details: {
      first_name: "xyz",
      last_name: "abc",
      groups: [
        {
          id: 1,
          group_type: "EXT"
        },
        {
          id: 2,
          group_type: "INT"
        }
      ],
      address_type: {
        city_name: "nashik",
        state: {
          code_name: "MH",
          name: "Maharashtra"
        }
      }
    }
  }
};

function toCamel(o) {
  var newO, origKey, newKey, value
  if (o instanceof Array) {
    return o.map(function(value) {
        if (typeof value === "object") {
          value = toCamel(value)
        }
        return value
    })
  } else {
    newO = {}
    for (origKey in o) {
      if (o.hasOwnProperty(origKey)) {
        newKey = _.camelCase(origKey)
        value = o[origKey]
        if (value instanceof Array || (value !== null && value.constructor === Object)) {
          value = toCamel(value)
        }
        newO[newKey] = value
      }
    }
  }
  return newO
}

console.log(toCamel(obj));    const obj = {
  vt_core_random: {
    user_details: {
      first_name: "xyz",
      last_name: "abc",
      groups: [
        {
          id: 1,
          group_type: "EXT"
        },
        {
          id: 2,
          group_type: "INT"
        }
      ],
      address_type: {
        city_name: "nashik",
        state: {
          code_name: "MH",
          name: "Maharashtra"
        }
      }
    }
  }
};

function toCamel(o) {
  var newO, origKey, newKey, value
  if (o instanceof Array) {
    return o.map(function(value) {
        if (typeof value === "object") {
          value = toCamel(value)
        }
        return value
    })
  } else {
    newO = {}
    for (origKey in o) {
      if (o.hasOwnProperty(origKey)) {
        newKey = _.camelCase(origKey)
        value = o[origKey]
        if (value instanceof Array || (value !== null && value.constructor === Object)) {
          value = toCamel(value)
        }
        newO[newKey] = value
      }
    }
  }
  return newO
}

console.log(toCamel(obj));

I have used lodash in this code.我在这段代码中使用了 lodash。

You can do this in a fairly generic fashion, writing a function which accepts an arbitrary key-transformation function and returning one which accepts an object and returns one with the same structure but with keys transformed.您可以以相当通用的方式执行此操作,编写一个函数,该函数接受任意键转换函数并返回一个接受对象并返回具有相同结构但键已转换的函数。 This is essentially no harder than writing code specifically for camelizing the keys.这本质上并不比编写专门用于骆驼键的代码难。

Here is one approach:这是一种方法:

 const fixKeys = (fn) => (obj) => Object .fromEntries ( Object .entries (obj) .map (([k, v]) => [ fn(k), Array .isArray (v) ? v .map (fixKeys (fn)) : typeof v == 'object' ? fixKeys (fn) (v) : v ]) ) const camelCase = (s) => s.replace(/_(.)/g, (s, c) => c.toUpperCase()) const camelizeKeys = fixKeys (camelCase) const obj = {vt_core_random: {user_details: {first_name: "xyz", last_name: "abc", groups: [{id: 1, group_type: "EXT"}, {id: 2, group_type: "INT"}], address_type: { city_name: "nashik", state: {code_name: "MH", name: "Maharashtra"}}}}} console .log (camelizeKeys (obj))

If Object.fromEntries is not available in your environment it's easy enough to shim or replace.如果Object.fromEntries在您的环境中不可用,则很容易填充或替换。 Also, this is tagged "lodash", and if you're already using it, you might want to replace some of the custom functionality here with lodash function, including the camelCase function and the Array and Object tests.此外,这被标记为“lodash”,如果您已经在使用它,您可能想用 lodash 函数替换这里的一些自定义功能,包括camelCase函数和数组和对象测试。 Or not, as this is already fairly simple.或者不,因为这已经相当简单了。

For those who are using typescript.对于那些使用打字稿的人。 I added typings to the accepted answer on this question.我在此问题的已接受答案中添加了类型。

const toCamel = (str: string): string => {
  return str.replace(/([_-][a-z])/gi, ($1: string) => {
    return $1.toUpperCase().replace('-', '').replace('_', '');
  });
};

const isArray = function (
  input: Record<string, unknown> | Record<string, unknown>[] | unknown
): input is Record<string, unknown>[] {
  return Array.isArray(input);
};

const isObject = function (
  obj: Record<string, unknown> | Record<string, unknown>[] | unknown
): obj is Record<string, unknown> {
  return (
    obj === Object(obj) && !Array.isArray(obj) && typeof obj !== 'function'
  );
};

const camelize = function <T>(input: T): T {
  return (function recurse<
    K extends Record<string, unknown> | Record<string, unknown>[] | unknown
  >(input: K): K {
    if (isObject(input)) {
      return Object.keys(input).reduce((acc, key) => {
        return Object.assign(acc, { [toCamel(key)]: recurse(input[key]) });
      }, {} as K);
    } else if (isArray(input)) {
      return input.map((i) => recurse(i)) as K;
    }
    return input;
  })(input);
};

I used the code from Donny Verduijn, but found that Date objects were getting converted to {} .我使用了来自 Donny Verduijn 的代码,但发现 Date 对象正在转换为{}

I also needed the ability to convert from snakeToCamel and camelToSnake so I added a formatter parameter.我还需要从snakeToCamel 和camelToSnake 转换的能力,所以我添加了一个格式化程序参数。

export const snakeToCamel = (str: string): string =>
  str.replace(/([_-][a-z])/gi, ($1: string) => $1.toUpperCase().replace('-', '').replace('_', ''));

export const camelToSnake = (str: string): string =>
  str.replace(/([A-Z])/g, ($1: string) => `_${$1.toLowerCase()}`);

const isArray = function (
  input: Record<string, unknown> | Record<string, unknown>[] | unknown
): input is Record<string, unknown>[] {
  return Array.isArray(input);
};

export const isObject = function (
  obj: Record<string, unknown> | Record<string, unknown>[] | unknown
): obj is Record<string, unknown> {
  return (
    isValidDate(obj) === false &&
    obj === Object(obj) &&
    !Array.isArray(obj) &&
    typeof obj !== 'function'
  );
};

const isValidDate = (value: any) => value instanceof Date;

const modifyObjectKeys = function <T>(input: T, formatter: (word: string) => string): T {
  return (function recurse<K extends Record<string, unknown> | Record<string, unknown>[] | unknown>(
    input: K
  ): K {
    if (isObject(input)) {
      return Object.keys(input).reduce(
        (acc, key) => Object.assign(acc, { [formatter(key)]: recurse(input[key]) }),
        {} as K
      );
    } else if (isArray(input)) {
      return input.map((i) => recurse(i)) as K;
    }
    return input;
  })(input);
};

/**
 *
 * @param input Object to convert keys to camelCase
 * @returns Object with keys converted to camelCase
 */
export const camelize = function <T>(input: T): T {
  return modifyObjectKeys(input, snakeToCamel);
};

/**
 *
 * @param input Object to convert keys to snake_case
 * @returns Object with keys converted to snake_case
 */
export const snakeify = function <T>(input: T): T {
  return modifyObjectKeys(input, camelToSnake);
};

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 camelCasedJson = jcc.camelCaseKeys(yourjsonData)

FP approach solution with lodash/fp使用 lodash/fp 的 FP 方法解决方案

import { camelCase, toPairs, fromPairs, map, compose, isArray, isObject } from 'lodash/fp';

const convertAllKeysToCamelCase = compose(
  fromPairs,
  map(([key, value]) => {
    if (isArray(value)) {
      return [camelCase(key), map(convertAllKeysToCamelCase, value)];
    }

    if (isObject(value)) {
      return [camelCase(key), convertAllKeysToCamelCase(value)];
    }

    return [camelCase(key), value];
  }),
  toPairs
);

convertAllKeysToCamelCase(myObj)

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

相关问题 递归地将对象字段从 camelCase 转换为 UPPERCASE - Recursively convert an object fields from camelCase to UPPERCASE 如何在打字稿中将蛇形字母转换为驼色字母? - How to convert snake case to camelcase in typescripts? 如何在我的应用程序中将蛇壳转换为骆驼壳 - How to convert snake case to camelcase in my app 对象,camelCase或snake_case中属性的标准命名约定是什么? - What is the standard naming convention of properties in a object, camelCase or snake_case? 将 snake_case 更改为 camelCase - Change snake_case to camelCase 在不使用 Lodash 的情况下,将 Object 密钥从 Snake Case 递归重命名为 Camel Case - Rename Object Keys from Snake Case to Camel Case Recursively Without Using Lodash 如何在camelCase PascalCase snake_case kebab-case (JS) 之间进行转换 - How to convert between camelCase PascalCase snake_case kebab-case (JS) 删除文件名的扩展名并使用正则表达式 vscode 片段将 camelCase 转换为蛇形大小写? - Remove the extension of filename and convert camelCase to snake case using regex vscode snippets? 将对象密钥从蛇形案例转换为骆驼案例,反之亦然的最佳方法是什么? - What is the best way convert object keys from snake case to camel case and vice versa? 从snake_case修改json密钥大小写为camelCase的简单方法 - Simple method to modify json keys casing to camelCase from snake_case
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM