JavaScript
Nested Objects
Data Manipulation
Flatten Objects
Coding Techniques

Fastest way to flatten / un-flatten nested JavaScript objects

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Flattening a nested JavaScript object means converting deep structure into key paths such as user.address.city. Un-flattening reverses the process. The fastest practical approach is usually a single traversal that writes into a result object, but performance only matters if the transformation is also reversible and unambiguous.

Decide on a Path Convention First

Before writing code, choose how paths are represented. Common options are:

  • dot notation such as user.name
  • bracket notation such as items[0].id
  • slash notation such as user/address/city

The convention matters because flattening and un-flattening must agree on how arrays, numbers, and keys containing dots are handled.

If you skip that design step, the “fast” function becomes useless on real data.

A Recursive Flatten Function

For ordinary objects and arrays, a recursive traversal is clear and fast enough for most applications.

javascript
1function flatten(value, prefix = "", out = {}) {
2  if (Array.isArray(value)) {
3    value.forEach((item, index) => {
4      const path = prefix ? `${prefix}.${index}` : String(index);
5      flatten(item, path, out);
6    });
7    return out;
8  }
9
10  if (value !== null && typeof value === "object") {
11    for (const [key, child] of Object.entries(value)) {
12      const path = prefix ? `${prefix}.${key}` : key;
13      flatten(child, path, out);
14    }
15    return out;
16  }
17
18  out[prefix] = value;
19  return out;
20}
21
22const nested = {
23  user: {
24    name: "Ana",
25    address: { city: "Toronto" }
26  },
27  tags: ["a", "b"]
28};
29
30console.log(flatten(nested));

This visits each property once, so the time cost is roughly proportional to the number of nodes in the structure.

Rebuild the Nested Object

Un-flattening walks each path and creates the missing containers.

javascript
1function unflatten(flat) {
2  const result = {};
3
4  for (const [path, value] of Object.entries(flat)) {
5    const parts = path.split(".");
6    let current = result;
7
8    for (let i = 0; i < parts.length; i++) {
9      const part = parts[i];
10      const isLast = i === parts.length - 1;
11      const nextIsIndex = /^\d+$/.test(parts[i + 1] || "");
12
13      if (isLast) {
14        current[part] = value;
15      } else {
16        if (!(part in current)) {
17          current[part] = nextIsIndex ? [] : {};
18        }
19        current = current[part];
20      }
21    }
22  }
23
24  return result;
25}
26
27console.log(unflatten({
28  "user.name": "Ana",
29  "user.address.city": "Toronto",
30  "tags.0": "a",
31  "tags.1": "b"
32}));

This produces nested objects again, including arrays when the next path segment looks numeric.

What “Fastest” Usually Means

For normal application code, the main performance wins come from:

  • one pass over the structure
  • avoiding repeated deep copies
  • avoiding expensive regex or string rebuilding inside tight loops when unnecessary
  • not serializing to JSON just to reshape keys

The complexity is still mostly linear in the number of values processed. For huge objects, recursion depth can become the real bottleneck rather than raw traversal speed.

If you expect extremely deep input, an explicit stack-based iterative implementation may be safer than recursion.

Reversibility Is Harder Than Flattening

Flattening is easy when you only need a display or logging format. It becomes harder when you need exact reversibility.

Examples of ambiguity include:

  • original keys that already contain dots
  • deciding whether a.0 means array index 0 or object key "0"
  • preserving special values such as Date, Map, or custom class instances

A robust flattening scheme must define those rules up front.

Common Pitfalls

  • Treating path format as an afterthought instead of a design choice.
  • Ignoring arrays and then discovering un-flattening cannot rebuild the original shape.
  • Using a reversible-looking format that breaks when keys contain dots.
  • Optimizing microseconds before confirming the transformation rules are correct.
  • Recursing into extremely deep structures without considering call-stack limits.

Summary

  • The practical fast approach is a single traversal that writes flattened paths into one result object.
  • Un-flattening must follow the same path convention or the transformation is not reversible.
  • Arrays, numeric keys, and dotted keys need explicit rules.
  • For most cases, recursion is clear and fast enough.
  • Correctness of the path scheme matters more than chasing a tiny performance gain.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.