Array.flat() in JavaScript: flattening an array of arrays

flat hands back a new array where nested arrays have been lifted one level up. One argument sets how deep the flattening goes.
3 min read
Believemy logo

Three API calls each handing back a list, an Array.map() producing one array per item, a file split line by line then word by word: the result is an array of arrays, where a single list was expected.

flat lifts that content one level up, with no loop and no accumulator.


Definition

flat hands back a new array in which the items that are themselves arrays have been replaced by their content. With no argument, one level is handled, and the original array stays intact.

JAVASCRIPT
const perPage = [["a", "b"], ["c"], ["d", "e"]];

console.log(perPage.flat());   // [ 'a', 'b', 'c', 'd', 'e' ]
console.log(perPage.length);   // 3, the original did not change

const mixed = ["alone", ["a", "b"]];
console.log(mixed.flat());     // [ 'alone', 'a', 'b' ]

Items that are not arrays go through the operation untransformed, which means flat can be called on a mixed list with no precaution.


Depth

The argument sets how many levels get lifted. It is 1 by default, and Infinity flattens everything, whatever the nesting.

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

console.log(deep.flat());          // [ 1, 2, [ 3, [ 4 ] ] ]
console.log(deep.flat(2));         // [ 1, 2, 3, [ 4 ] ]
console.log(deep.flat(Infinity));  // [ 1, 2, 3, 4 ]
Good to know

Infinity is tempting, but it erases one piece of information: the structure. On data whose shape you do not control, flattening everything turns a hierarchy into a flat list nobody can rebuild. State the depth you actually expect.


flatMap, the most common pairing

Transforming then flattening one level is so frequent that one method combines both. flatMap is equivalent to Array.map() followed by flat(), in a single pass.

JAVASCRIPT
const lines = ["fr en", "es de"];

console.log(lines.map((l) => l.split(" ")));      // [ [ 'fr', 'en' ], [ 'es', 'de' ] ]
console.log(lines.flatMap((l) => l.split(" ")));  // [ 'fr', 'en', 'es', 'de' ]

The depth of flatMap is fixed at one level and cannot be tuned. For more, go back to map then flat(n).


Frequently asked questions

Question

Does flat change the original array?

No, it builds a new one. The copy stays shallow all the same: the objects held inside are the same on both sides, and changing one of their properties shows up in both arrays.


Question

What happens to holes in an array?

They disappear. An array written with consecutive commas holds slots that were never defined, and flat drops them on the way: [1, , 3].flat() hands back [1, 3]. It is one of the few clean ways to clear those holes, which almost always come from new Array(n).


Question

How do you merge several API results?

By gathering the responses into an array, then calling flat() once. With Promise and Promise.all, the result is precisely an array of arrays: const all = (await Promise.all(calls)).flat(); gives the single list expected.

Related terms

Discover our javaScript glossary

Every word of JavaScript explained simply: keywords, built-in objects, methods, errors and concepts. Clear definitions and examples that actually run, to learn and to troubleshoot.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.