簡體   English   中英

遞歸地將 object 字段從蛇形大小寫轉換為駝峰大小寫

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

我有一個像這樣的 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"
        }
      }
    }
  }
};

我想遞歸地將其字段轉換為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"
        }
      }
    }
  }
};

我嘗試使用 mapKeys() 但我無法理解其中的遞歸部分。 非常感謝任何幫助。 如果它使過程更簡單,我也有能力使用lodash

您可以使用 lodash 的_.transform()創建一個遞歸函數,該函數迭代鍵並使用_.camelCase()將它們轉換為駝峰式大小寫。 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>

你可以嘗試這樣的事情:

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

對於所有使用 lodash 的人,我已經修改了已接受的答案,因為 lodash 已經包含了實用函數,如isArray isObject camelCase

所以代碼簡化為這個。 :)

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

我在這段代碼中使用了 lodash。

您可以以相當通用的方式執行此操作,編寫一個函數,該函數接受任意鍵轉換函數並返回一個接受對象並返回具有相同結構但鍵已轉換的函數。 這本質上並不比編寫專門用於駱駝鍵的代碼難。

這是一種方法:

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

如果Object.fromEntries在您的環境中不可用,則很容易填充或替換。 此外,這被標記為“lodash”,如果您已經在使用它,您可能想用 lodash 函數替換這里的一些自定義功能,包括camelCase函數和數組和對象測試。 或者不,因為這已經相當簡單了。

對於那些使用打字稿的人。 我在此問題的已接受答案中添加了類型。

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

我使用了來自 Donny Verduijn 的代碼,但發現 Date 對象正在轉換為{}

我還需要從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);
};

使用 npm json-case-handler這將允許您在一行中執行此操作。

它可以轉換任何嵌套對象

對於您的情況,您可以這樣做:

const jcc = require('json-case-convertor')
const camelCasedJson = jcc.camelCaseKeys(yourjsonData)

使用 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM