Search code examples
javascriptlodash

How to change key name with map into nested object?


Here is the object

{
  a: 1,
  b: {
   c: {
     d: 2
   },
   e: 3
  }
}


Here is the map

{
  'a': 'aaa',
  'b': 'bbb',
  'b.c.d': 'bcd'
}

Here is the expected result.

{
  aaa: 1,
  bbb: {
   c: {
     bcd: 2
   },
   e: 3
  }
}

I know there's a function in lodash _.get could get the value like b.c.d.
But how can I change the key name with the map?


Solution

  • You can do this recursively by keeping track of the current path and building a key into the map with that:

    let o = {a: 1,b: {c: {d: 2},e: 3}}
    let map =  {
        'a': 'aaa',
        'b': 'bbb',
        'b.c.d': 'bcd'
    }
    
    function makeObj(obj, map, p=[]) {
        let ret = {}
        Object.entries(obj).forEach(([k, v]) => {
            let path = p.concat(k)                  // add onto current path
            let mapKey = map[path.join('.')] || k
            
            ret[mapKey] = (typeof v === 'object')
                ? makeObj(v, map, path)             // if an object recurse and pass on the current path  
                : v                                 // otherwise set the value
        })
        return ret
    }
    
    console.log(makeObj(o, map))