The flat() and flatMap() methods

The flat() and flatMap() methods

Learn how JavaScript's flat() and flatMap() work: default depth, flat(Infinity), dropping holes, and using flatMap as a combined map and filter.

Martin Ferret

Martin Ferret

August 11, 2026

For a long time, flattening a nested array in JavaScript meant reaching for a loop or a reduce. The flat() and flatMap() methods, introduced in ES2019, cover that need in a way that is readable and direct.

flat() creates a new array with all sub-array elements pulled up by one or more levels. By default, it only pulls up a single level.

      const nested = [1, [2, 3], [4, 5]];
const flat = nested.flat();

console.log(flat); // → [1, 2, 3, 4, 5]

    

Read it as: "lift the elements of the sub-arrays up by one level."

Why flat() With No Argument Is Not Enough

By default, flat() only descends one level. As soon as the structure is nested deeper than that, the result surprises you.

      const deep = [1, [2, [3, [4]]]];

deep.flat();         // → [1, 2, [3, [4]]]  only one level removed
deep.flat(2);        // → [1, 2, 3, [4]]
deep.flat(Infinity); // → [1, 2, 3, 4]      flattens every level, whatever the depth

    

The mental model: flat() asks "how many levels should I go down?", and the default answer is: just one.

CallBehavior
flat()depth of 1 (the default)
flat(2)descends 2 levels
flat(Infinity)flattens the entire depth, however deep
flat(0)changes nothing, returns a shallow copy

A Useful Side Effect: Holes Are Removed

flat() also drops the empty slots (holes) of a sparse array as it goes, something map() does not do.

      const sparse = [1, , 3, [4, , 6]];

console.log(sparse.flat()); // → [1, 3, 4, 6]  the holes are gone

    

Sometimes that is exactly what you want, and sometimes it is a surprise: worth keeping in mind if the array can contain holes.

flatMap(): Map, Then Flatten

flatMap() combines map() and flat() in a single pass: it applies a function to each element, then flattens the result by one level.

      const numbers = [1, 2, 3];
const result = numbers.flatMap(n => [n, n * 2]);

console.log(result); // → [1, 2, 2, 4, 3, 6]

    

With map() alone, you would get an array of arrays that you then have to flatten yourself:

      numbers.map(n => [n, n * 2]);
// → [[1, 2], [2, 4], [3, 6]]

    

In other words, arr.flatMap(fn) is identical to arr.map(fn).flat() (a flat() of depth 1), but slightly more efficient than calling the two methods separately, since it does not build a full intermediate array of arrays.

The One-to-Zero Case: flatMap() as map and filter Combined

Because the callback can return an array of any length, returning [] drops the element and returning several values adds them. That turns flatMap() into a combined map and filter.

      const values = [5, -2, 8, -1, 3];

// Keep the positives, double them, and drop the negatives
const positives = values.flatMap(n => n > 0 ? [n * 2] : []);

console.log(positives); // → [10, 16, 6]

    

This is a common idiom: where a filter followed by a map needed two passes, flatMap does the filtering and the transforming in a single expression. Like map(), it also skips holes in a sparse array.

💡 flatMap() only flattens one level, and that level is not configurable: there is no flatMap(fn, depth). If the callback returns arrays nested more than one level deep, chain a flat() afterward: arr.flatMap(fn).flat(Infinity). This is deliberate: flatMap is built for the common one-to-many case, not for deep flattening.

      [1, 2].flatMap(n => [[n]]);
// → [[1], [2]]  only one level removed, the inner arrays remain

    

Conclusion

flat() and flatMap() replace verbose loops and reduce calls with two readable methods. Use flat() to level out a structure you have already built, with Infinity when the depth is unknown. Use flatMap() to transform and flatten in a single pass, where it shines whenever each element produces zero, one, or several values.

In any code that builds lists out of other lists, these two methods make intent explicit, and intent is what separates readable code from clever code.

More certificates.dev articles

Get the latest news and updates on developer certifications. Content is updated regularly, so please make sure to bookmark this page or sign up to get the latest content directly in your inbox.