How to Flatten Js Object

2020-12-05

If you used lodash, mongo and bunch of other js libraries and frameworks you’ve seen APIs where you can access nested properties as strings. Something like get('address.street'). Sometimes you might want to make something similar using that pattern. There are a bunch of packages which do that and most utility packages provide a helper for that. But it’s actually quite easy to achieve with few lines of js.

So before I forget and so that I can remember it in the future I’m just going to put the snippet I’ve come up with here.

// null is object as well, don't forget that
const isObject = (o) => o !== null && typeof o === "object";

// only the first value needs to be provided to kick
// off the function
function flattenKeys(value, prefix, memo = {}) {
  // if it's not an object we end the recursion
  if (!isObject(value)) {
    return (memo[prefix] = value);
  }
  // checking for empty, this is to avoid the
  // `.` in the initial start
  let _prefix = !!prefix ? `${prefix}.` : "";
  // pass in memo to be mutated and recursevly fill
  // in the key paths
  Object.entries(value).forEach(([key, nextValue]) =>
    flattenKeys(nextValue, `${_prefix}${key}`, memo)
  );

  // finally return
  return memo;
}

It might be not the most optimal solution, but it works good enough for most cases. To use this:

let fields = {
  name: 'tom',
  address: {
    street: 'Main',
    country: 'uk'
  },
  likes: ['ice cream', 'food']
}

flattenKeys(fields)

This will give you:

{
  "name": "tom",
  "address.street": "Main",
  "address.country": "uk",
  "likes.0": "ice cream",
  "likes.1": "food"
}

Tags