Jaakko Karhu Jaakko Karhu - 3 months ago 9
Javascript Question

How to change object keys in deeply nested object with lodash?

I have a following kind of object:

{
options: [
{ id: 1, value: 'a' }
],
nestedObj: {
options: [
{ id: 2, value: 'b' }
]
}
}


How do I change the key 'id' on both, options array in first level and in the nested level? I have tried to use lodash for this but not have been able to get the desired result:

{
options: [
{ newKey: 1, value: 'a'
],
nestedObj: {
options: [
{ newKey: 2, value: 'b' }
]
}
}


So I would like to find a function which works like lodash mapKeys but would iterate through deep nested object.

Answer

You can using _.transform() recursively to replace keys:

var obj = {
  options: [{
    id: 1,
    value: 'a'
  }],
  nestedObj: {
    options: [{
      id: 2,
      value: 'b'
    }]
  }
};

console.log(replaceKeysDeep(obj, {
  id: 'newKey',
  options: 'items'
}));

function replaceKeysDeep(obj, keysMap) { // keysMap = { oldKey1: newKey1, oldKey2: newKey2, etc...
  function replaceKeys(obj) { // the inner function which will be called recursivley

    return _.transform(obj, function(result, value, key) { // transform to a new object

      var currentKey = keysMap[key] || key; // if the key is in keysMap use the replacement, if not use the original key

      result[currentKey] = _.isObject(value) ? replaceKeys(value) : value; // if the key is an object run it through the inner function - replaceKeys
    });
  }

  return replaceKeys(obj); // return the inner function result
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.js"></script>