JavaScript: how do I flatten an object like this

how do we implement a util flatten to flat this

myMap = {
  'a': 5,
  'b': 6,
  'c': {
    'f': 9,
    'g': {
      'm': 17,
      'n': 3
    }
  }
}

to

flatten(myMap) = {
  'a': 5,
  'b': 6,
‍‌‌‍‌‍‌‍‍‌‍‍‍‍‍‌‍‌‍‍ 'c.f': 9,
  'c.g.m': 17,
  'c.g.n': 3,
}

?

I found here is an implementation https://github.com/lukeed/flattie/blob/master/src/index.js but I couldn’t understand the code. Can someone please give me a more readable version?

Answer

Here is perhaps a slightly simpler version:

const inputObject = {
  a: 5,
  b: 6,
  c: {
    f: 9,
    g: {
      m: 17,
      n: 3
    }
  }
}

function flatten(input, keys = [], output = {}) {
  for (key in input) {
    const value = input[key]
    const combinedKeys = [...keys, key]

    if (typeof value === 'object') {
      output = flatten(value, combinedKeys, output)
    } else {
      output[combinedKeys.join('.')] = value
    }
  }
  return output
}

console.log(flatten(inputObject))
/* Logs:
 * {
 *   "a": 5,
 *   "b": 6,
 *   "c.f": 9,
 *   "c.g.m": 17,
 *   "c.g.n": 3
 * }
 */

The idea is to recursively look at all properties of the object and build a .-separated key as we go deeper until we reach a leaf value.

You can read more about recursive functions here: https://www.freecodecamp.org/news/what-is-recursion-in-javascript/