DEV Community

Gurmeet Singh
Gurmeet Singh

Posted on

Flatten a nested object in JS

When an interviewer wants to test your logical as well as programming capabilities a good-to-go question for them is to ask you to write a function to flatten a given nested object. Such that, an object as given below

{
    "companyName": "Movetoabroad",
    "fieldOfWork": "Immigartaion",
    "website": "http://movetoabroad.com",
    "highlights": {
        "visaSuccessRate": "High",
        "fees": "Free"
    }
};
Enter fullscreen mode Exit fullscreen mode

must become

{
  "companyName": "Movetoabroad",
  "fieldOfWork": "Immigartaion",
  "website": "http://movetoabroad.com",
  "highlights.visaSuccessRate": "High",
  "highlights.fees": "Free"
}
Enter fullscreen mode Exit fullscreen mode

Seems simple. Right? We can just add a check to see if the value of the property is object if yes just iterate over the child object and prepend the parent property name to the child property name before adding it to a new object which contains all the flattened properties.

But in most cases, the interviewer will add a condition here that the object can have an "n" level of nesting. Such that, we can have an object in the form of

{
  "companyName": "Movetoabroad",
  "fieldOfWork": "Immigartaion",
  "website": "http://movetoabroad.com",
  "highlights": {
    "visaSuccessRate": "High",
    "fees": "Free",
    "timings": {
      "weekdays": "9am - 6pm",
      "weekends": "10am - 7pm",
    },
  },
}
Enter fullscreen mode Exit fullscreen mode

which must become

{
  "companyName": "Movetoabroad",
  "fieldOfWork": "Immigartaion",
  "website": "http://movetoabroad.com",
  "highlights.visaSuccessRate": "High",
  "highlights.fees": "Free",
  "highlights.timings.weekdays": "9am - 6pm",
  "highlights.timings.weekends": "10am - 7pm",
}
Enter fullscreen mode Exit fullscreen mode

Now the logic which you thought earlier still applies but since the level of nesting is unknown we have to keep on applying the same logic again and again until the nesting stops. You can think of doing it using a loop but here's where the programming abilities kick in and you must think about using Recursion

One common way to solve this is -

const flattenObj = (obj) => {
  const result = {};
  for (let key in obj) {
    if (typeof obj[key] === "object") {
      const temp = flattenObj(obj[key]);
      for (let prop in temp) {
        result[key + "." + prop] = temp[prop];
      }
    } else {
      result[key] = obj[key];
    }
  }
  return result;
};

Enter fullscreen mode Exit fullscreen mode

Or even better

function flattenObj(obj, res = {}, parentKey = '') {
    for(let key in obj) {
    let modifiedKeyName = parentKey ? `${parentKey}.${key}` : key;
    if(typeof obj[key] == 'object') {
        flattenObj(obj[key], res, modifiedKeyName);
    }else{
        res[modifiedKeyName] = obj[key];
    }
  }
  return res;
}
Enter fullscreen mode Exit fullscreen mode

Disclaimer - This code must be considered only for interview purposes for real-world usage you might need to optimize it more based on the objects you are passing to this function. For instance, if the value of a property is an array then you might need to add another check Array.isArray(obj[key]) along with typeof obj[key] == 'object' because in JS typeof arrays also returns "object".

Top comments (0)