DEV Community

Cover image for Flatten the Object - JavaScript
AbhishekkGautam
AbhishekkGautam

Posted on

Flatten the Object - JavaScript

Hello, Hope you're doing well & solving interesting problems using your programming skills.πŸ”₯

In this blog, we will try to solve one such interesting problem related to flattening the object which is asked in javascript interviews.

I have breakdown the whole tutorial into 4 sections -

  1. Input
  2. Output
  3. Approach (logic)
  4. Assemble (put everything together)

Let's start!πŸš€

Input

This is our unflatten object containing data of an user.

const user = {
  name: 'John',
  address: {
    personal: {
      street: 'Victor Plains',
      city: 'Wisokyburgh',
    },
    office: {
      city: 'South Elvis',
      area: {
        landmark: 'Hoeger Mall',
      },
    },
  },
};
Enter fullscreen mode Exit fullscreen mode

Output

We need to flat the object like this -

{
  user_name: "John",
  user_address_personal_street: "Victor Plains",
  user_address_personal_city: "Wisokyburgh",
  user_address_office_city: "South Elvis",
  user_address_office_area_landmark: "Hoeger Mall"
}
Enter fullscreen mode Exit fullscreen mode

Approach

If you closely look at our input object, you'll see a pattern of nested objects.

const OBJECT = {
  name: 'John',
  OBJECT: {
    OBJECT: {
      street: 'Victor Plains',
      city: 'Wisokyburgh',
    },
    OBJECT: {
      city: 'South Elvis',
      OBJECT: {
        landmark: 'Hoeger Mall',
      },
    },
  },
};
Enter fullscreen mode Exit fullscreen mode

So we need to iterate over the nested objects & flat them one by one.
But if we want to flat each object at a time, we need to breakdown the nested objects into a single object recursively.

Recursively? πŸ€”

Yes, We will use recursion to solve this problem.

What is Recursion?

Recursion is a phenomenon used to solve complex problems by breaking them down into simpler ones.

Recursive Function

When we apply this phenomenon in a function, that function will call itself again and again until we reach at the breaking condition.

*Let's define our recursive function - *

const recursiveFunc = (obj, parentKey, flattenObj) => { 
  // we will write our logic here.
};
Enter fullscreen mode Exit fullscreen mode
  • obj: our input object
  • parentKey: To keep a track of parent object because we need to append parent keys while iterating over the input obj - user_address_office_area_landmark: "Hoeger Mall"
  • flattenObj: an empty object to store flatten obj on each iteration.

While looping through unflatten object, we will only flat those key whose type is object.

So, we need a function which takes key as item & return true if the key is an object.

const isAnObject = (item) => {
    return (
      item !== null &&
      typeof item === 'object' &&
      Object.prototype.toString.call(item) === '[object Object]'
    );
  };
Enter fullscreen mode Exit fullscreen mode

Now we need to loop through the input object ( unflatten ) & store the flatten key-value pair inside flattenObj

for (let key in obj) { // 1
    let finalKey = `${parentKey}_${key}`; // 2
    if (isAnObject(obj[key])) { // 3
      recursiveFunc(obj[key], finalKey, flattenObj); // 4
    } else {
      flattenObj[finalKey] = obj[key]; // 5
    }
  }
Enter fullscreen mode Exit fullscreen mode

Let's understand it line by line.

// 1 - let key in obj this line will give key of the key-value pair on each iteration. name, address, personal & so on.

// 2 - we are adding the parent key before current key to make it look like this at the end - user_address_personal_street: "Victor Plains". When we iterate over address obj, the user will be the parent. so we add the user before address - user_address & store it in finalKey.

// 3 - we are checking if the current key is an object or not using isAnObject function which we've already defined.

// 4 - If the key is an object, we will call recursiveFunc again with the updated value of obj, parentKey & flattenObj.

// 5 - If the key is not object, we will store the finalKey (user_address_personal_street) as key & key("Victor Plains") as value inside flattenObj.

Let's pass our initial data & console the output.

let flattenObj = {};
recursiveFunc(user, 'user', flattenObj);
console.log(flattenObj);
Enter fullscreen mode Exit fullscreen mode

So when we invoke the recursiveFunc, it'll run the loop & iterate over user object.
Initial value -

  1. obj: user
  2. parentKey: 'user'
  3. flattenObj: {}

First Iteration

Now key is name

  • finalKey = 'user_name'
  • name is not an object Result
flattenObj = { user_name: "John" }
Enter fullscreen mode Exit fullscreen mode

Second Iteration

Now key is address

  • finalKey = 'user_address'
  • address is an object

Result
call recursiveFunc again with new values -

  • obj: address
  • parentKey: "user_address"
  • flattenObj: { user_name: "John" }

Third Iteration

Now key is personal

  • finalKey = 'user_address_personal'
  • personal is an object

Result
call recursiveFunc again with new values -

  • obj: personal
  • parentKey: "user_address_personal"
  • flattenObj: { user_name: "John" }

Fourth Iteration

Now key is street

  • finalKey = 'user_address_personal_street'
  • street is not an object

Result

flattenObj = { 
  user_name: "John",
  user_address_personal_street: "Victor Plains"
}
Enter fullscreen mode Exit fullscreen mode

...and iterations will go on until it reach the last key.
The final output will be - πŸŽ‰

flattenObj = {
  user_name: "John",
  user_address_personal_street: "Victor Plains",
  user_address_personal_city: "Wisokyburgh",
  user_address_office_city: "South Elvis",
  user_address_office_area_landmark: "Hoeger Mall"
}
Enter fullscreen mode Exit fullscreen mode

Assemble

Here's the whole code for flattening an object.

const user = {
  name: 'John',
  address: {
    personal: {
      street: 'Victor Plains',
      city: 'Wisokyburgh',
    },
    office: {
      city: 'South Elvis',
      area: {
        landmark: 'Hoeger Mall',
      },
    },
  },
};

const recursiveFunc = (obj, parentKey, flattenObj) => { 
  const isAnObject = (item) => { 
    return (
      item !== null &&
      typeof item === 'object' &&
      Object.prototype.toString.call(item) === '[object Object]'
    );
  };

  for (let key in obj) { 
    let finalKey = `${parentKey}_${key}`; 
    if (isAnObject(obj[key])) {
      recursiveFunc(obj[key], finalKey, flattenObj); 
    } else {
      flattenObj[finalKey] = obj[key]; 
    }
  }
};

let flattenObj = {};
recursiveFunc(user, 'user', flattenObj);
console.log(flattenObj);

Enter fullscreen mode Exit fullscreen mode

Conclusion

Hope after reading this blog, you've understood -

  1. How to approach a problem.
  2. How to flatten an object using recursion.

If you find this blog as helpful, don't forget to share it.
And incase you know any other ways to flatten an object in javaScript, please share it in the comments.

Thank you πŸ™‚
Connect with me on - Twitter Instagram

Top comments (0)