DEV Community

Nandan Kumar
Nandan Kumar

Posted on • Originally published at blog.nandan.dev on

How to Convert Nested Objects to Flat Objects in JavaScript.

How to Convert Nested Objects to Flat Objects in JavaScript

I am sure you have been asked this question in one of the interviews.

It looks simple at first. But the interviewer is actually checking whether you understand recursion, objects, and how JavaScript treats arrays.

So basically, you are given a nested object, and you are expected to simplify it by removing the nesting and printing it in a non-nested format.

Here is a simple input and output :

const input = {
  a: 1,
  b: {
    c: 2,
    d: {
      e: 3
    }
  }
};

Enter fullscreen mode Exit fullscreen mode

Output:

 { a: 1, 
    b_c: 2, 
    b_d_e: 3, 
 }

Enter fullscreen mode Exit fullscreen mode

Now look at the solution :

function flatten(obj, prefix = "", res = {}) {
    // Loop through every key in the object
    for (let key in obj) {

        // Skip properties coming from prototype chain
        if (!obj.hasOwnProperty(key)) return;

        // If prefix exists, append current key using _
        // Otherwise just use the key itself
        let objKey = prefix ? `\({prefix}_\){key}` : key;

        let value = obj[key];

        // If value is an object and not null,
        // recursively flatten it
        if (typeof value === 'object' && value !== null) {
            flatten(value, objKey, res);
        } else {
            // If it's a primitive value, assign it directly
            res[objKey] = value;
        }
    }

    // Return the accumulated result
    return res;
}

Enter fullscreen mode Exit fullscreen mode

Let us test it.

const input = {
  a: 1,
  b: {
    c: 2,
    d: {
      e: [1, 2]
    }
  }
};

console.log(flatten(input));

// {a: 1, b_c: 2, b_d_e_0: 1, b_d_e_1: 2 }

Enter fullscreen mode Exit fullscreen mode

Now observe something interesting.

It flattens the nested object correctly.

But it also destructures the array and adds indexes as keys.

Why do you think that happened?

💡

As you know, everything in JavaScript is an object. Even Arrays.

So when we check:

typeof value === 'object'

Enter fullscreen mode Exit fullscreen mode

Arrays also satisfy that condition.

That means our recursive call is going inside arrays as well, and treating indexes (0, 1) like object keys.

That is why we are getting:

b_d_e_0: 1
b_d_e_1: 2

Enter fullscreen mode Exit fullscreen mode

So, how do we fix it?

Simple.

We add one more condition to ignore Arrays.

function flatten(obj, prefix = "", res = {}) {
    for (let key in obj) {

        // Ensure we are working only with object's own properties
        if (!obj.hasOwnProperty(key)) return;

        let objKey = prefix ? `\({prefix}_\){key}` : key;
        let value = obj[key];

        // Only recurse if:
        // 1. value is an object
        // 2. value is not null
        // 3. value is NOT an array
        if (
            typeof value === 'object' &&
            value !== null &&
            !Array.isArray(value)
        ) {
            flatten(value, objKey, res);
        } else {
            // Directly assign primitives and arrays
            res[objKey] = value;
        }
    }

    return res;
}

Enter fullscreen mode Exit fullscreen mode

Testing Both Cases

const input1 = {
  a: 1,
  b: {
    c: 2,
    d: {
      e: [1, 2]
    }
  }
};

const input2 = {
  a: 1,
  b: {
    c: 2,
    d: {
      e: 3
    }
  }
};

console.log(flatten(input1));
console.log(flatten(input2));

// { a: 1, b_c: 2, b_d_e: [1, 2] }
// { a: 1, b_c: 2, b_d_e: 3 }

Enter fullscreen mode Exit fullscreen mode

That is it.

A simple recursion problem. But it tests whether you truly understand:

  • How objects work

  • How arrays behave internally

  • How recursion accumulates results

  • And how small edge cases can break your logic

This is why interviewers love this question.

That’s all, folks! I hope you found this helpful. If you enjoyed this, check out more articles on my Blog, https://blog.nandan.dev/

Feel free to comment, email me at connect@nandan.dev, or connect with me on Twitter, Instagram, or GitHub. Don’t forget to subscribe to my newsletter for regular updates on JavaScript topics!

Twitter | Instagram | Github | Website

Top comments (0)