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',
personal: {
street: 'Victor Plains',
city: 'Wisokyburgh',
},
office: {
city: 'South Elvis',
area: {
landmark: 'Hoeger Mall',
},
},
},
};
``````

## Output

We need to flat the object like this -

``````{
user_name: "John",
}
``````

## 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',
},
},
},
};
``````

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.
};
``````
• 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]'
);
};
``````

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
}
}
``````

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);
``````

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" }
``````

## Second Iteration

Now `key` is `address`

• `address` is an object

Result
call recursiveFunc again with new values -

• `flattenObj: { user_name: "John" }`

## Third Iteration

Now `key` is `personal`

• `personal` is an object

Result
call recursiveFunc again with new values -

• obj: personal
• `flattenObj: { user_name: "John" }`

## Fourth Iteration

Now `key` is `street`

• `street` is not an object

Result

``````flattenObj = {
user_name: "John",
}
``````

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

``````flattenObj = {
user_name: "John",
}
``````

## Assemble

Here's the whole code for flattening an object.

``````const user = {
name: 'John',
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);

``````

## 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