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.
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.
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 ]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.
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
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.
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).
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.