Skip to content

Home

Transform the keys of a JavaScript object

JavaScript objects are a fundamental data structure in the language, and they are used to store collections of key-value pairs. Transforming object keys can come in handy in many different situations, but requires a little bit of work to get it right.

Map object keys

Given an object and a function, you can generate a new object by mapping the keys of the original object using the provided function.

In order to do so, you can use Object.keys() to iterate over the object's keys and Array.prototype.reduce() to create a new object with the same values and mapped keys using the provided function, fn.

const mapKeys = (obj, fn) =>
  Object.keys(obj).reduce((acc, k) => {
    acc[fn(obj[k], k, obj)] = obj[k];
    return acc;
  }, {});

mapKeys({ a: 1, b: 2 }, (val, key) => key + val); // { a1: 1, b2: 2 }
💬 Note

Similarly, you can transform the values of an object using the same approach. Simply use Object.entries() or Object.values() instead of Object.keys().

Deep map object keys

The previous snippet only works for the keys at the first level of the object. In order to transform nested keys, you'll have to use recursion.

Again, using Object.keys() to iterate over the object's keys, you can use Array.prototype.reduce() to create a new object with the same values and mapped keys using the provided function, fn. If the value of a key is an object, you can call the function recursively to transform its keys as well.

const deepMapKeys = (obj, fn) =>
  Array.isArray(obj)
    ? obj.map(val => deepMapKeys(val, fn))
    : typeof obj === 'object'
    ? Object.keys(obj).reduce((acc, current) => {
        const key = fn(current);
        const val = obj[current];
        acc[key] =
          val !== null && typeof val === 'object' ? deepMapKeys(val, fn) : val;
        return acc;
      }, {})
    : obj;

const obj = {
  foo: '1',
  nested: {
    child: {
      withArray: [
        {
          grandChild: ['hello']
        }
      ]
    }
  }
};
const upperKeysObj = deepMapKeys(obj, key => key.toUpperCase());
/* {
  "FOO":"1",
  "NESTED":{
    "CHILD":{
      "WITHARRAY":[
        {
          "GRANDCHILD":[ 'hello' ]
        }
      ]
    }
  }
} */

Rename object keys

one of the simplest transformations is renaming the keys of an object. You can use Object.keys() in combination with Array.prototype.reduce() and the spread operator (...) to get the object's keys and rename them according to a given dictionary, keysMap.

const renameKeys = (keysMap, obj) =>
  Object.keys(obj).reduce(
    (acc, key) => ({
      ...acc,
      ...{ [keysMap[key] || key]: obj[key] }
    }),
    {}
  );

const obj = { name: 'Bobo', job: 'Front-End Master', shoeSize: 100 };
renameKeys({ name: 'firstName', job: 'passion' }, obj);
// { firstName: 'Bobo', passion: 'Front-End Master', shoeSize: 100 }
💬 Note

A very common key transformation is to convert all the keys of an object to upper or lower case. In the previous article, can find a more detailed explanation of how to uppercase or lowercase object keys in JavaScript.

Symbolize object keys

Symbols are often underused in JavaScript, but they can be very useful for creating unique keys. In order to symbolize the keys of an object, you can use Object.keys() to get the keys of the object and Array.prototype.reduce() to create a new object where each key is converted to a Symbol.

const symbolizeKeys = obj =>
  Object.keys(obj).reduce(
    (acc, key) => ({ ...acc, [Symbol(key)]: obj[key] }),
    {}
  );

symbolizeKeys({ id: 10, name: 'apple' });
// { [Symbol(id)]: 10, [Symbol(name)]: 'apple' }

Transform object keys using a function

Subsequently, you might want to completely transform the keys of an object using a function. In that case, you can apply a function against an accumulator and each key in the object (from left to right) using Object.keys() and Array.prototype.reduce().

const transform = (obj, fn, acc) =>
  Object.keys(obj).reduce((a, k) => fn(a, obj[k], k, obj), acc);

transform(
  { a: 1, b: 2, c: 1 },
  (r, v, k) => {
    (r[v] || (r[v] = [])).push(k);
    return r;
  },
  {}
); // { '1': ['a', 'c'], '2': ['b'] }

More like this

Start typing a keyphrase to see matching snippets.