Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursively convert an object fields from snake case to camelCase

I had an object like this (fields in 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

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. any help is highly appreciated. Also I have the ability to use lodash if it makes the process any simpler

like image 285
Malik Bagwala Avatar asked Jan 16 '20 12:01

Malik Bagwala


2 Answers

You can use lodash's _.transform() to create a recursive function that iterates the keys and converts them camel case with _.camelCase(). Transform can also handle arrays, so if the iterated object (target) is an array, we don't need to change the keys.

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>
like image 50
Ori Drori Avatar answered Oct 04 '22 08:10

Ori Drori


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(/([-_][a-z])/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));
like image 28
qiAlex Avatar answered Oct 04 '22 08:10

qiAlex