flat and flatMap
Arrays can contain other arrays.
For example:
const groups = [
["Alice", "Bob"],
["Charlie", "Dana"],
["Eve"],
];This is called a nested array.
Nested arrays are useful, but sometimes you need one simple array instead.
JavaScript gives you two methods for this:
.flat().flatMap()
What Does Flattening Mean?
Flattening means taking nested arrays and turning them into a less nested array.
Example:
const nested = [
[1, 2],
[3, 4],
[5, 6],
];
const flat = nested.flat();
console.log(flat); // [1, 2, 3, 4, 5, 6]The original array has arrays inside it.
The flattened array contains the values directly.
The flat Method
The .flat() method creates a new array with nested arrays flattened.
const numbers = [[1, 2], [3, 4], [5]];
const result = numbers.flat();
console.log(result); // [1, 2, 3, 4, 5]
console.log(numbers); // [[1, 2], [3, 4], [5]]flat() does not mutate the original array.
It returns a new array.
Default Depth
By default, .flat() flattens one level deep.
const nested = [1, [2, 3], [4, [5, 6]]];
const result = nested.flat();
console.log(result); // [1, 2, 3, 4, [5, 6]]The array [2, 3] was flattened.
The array [4, [5, 6]] was flattened one level.
But [5, 6] is still nested because it was two levels deep.
Flattening More Than One Level
You can pass a depth argument to .flat().
const nested = [1, [2, 3], [4, [5, 6]]];
const result = nested.flat(2);
console.log(result); // [1, 2, 3, 4, 5, 6]flat(2) means:
Flatten up to two levels deep.Another example:
const deeplyNested = [1, [2, [3, [4]]]];
console.log(deeplyNested.flat(1)); // [1, 2, [3, [4]]]
console.log(deeplyNested.flat(2)); // [1, 2, 3, [4]]
console.log(deeplyNested.flat(3)); // [1, 2, 3, 4]Flattening All Levels
If you want to flatten all levels, you can use Infinity.
const deeplyNested = [1, [2, [3, [4]]]];
const result = deeplyNested.flat(Infinity);
console.log(result); // [1, 2, 3, 4]Use this carefully.
It is convenient, but if your data is deeply nested for a reason, flattening everything may remove useful structure.
Practical Example: Combining Groups
Imagine users are grouped by team:
const teams = [
["Alice", "Bob"],
["Charlie"],
["Dana", "Eve"],
];If you want one list of all users:
const allUsers = teams.flat();
console.log(allUsers); // ["Alice", "Bob", "Charlie", "Dana", "Eve"]This is clearer than using reduce for simple flattening:
const allUsers = teams.reduce((result, team) => {
return result.concat(team);
}, []);Both work.
But for simple flattening, flat() communicates your intent directly.
Practical Example: API Results
Sometimes API data comes grouped.
const categoryResults = [
[
{ id: 1, title: "JavaScript Basics" },
{ id: 2, title: "Array Methods" },
],
[
{ id: 3, title: "DOM Events" },
],
];
const lessons = categoryResults.flat();
console.log(lessons);Now you have one array of lesson objects.
This makes it easier to search, filter, map, or render the list.
flat and Empty Slots
flat() removes empty slots from arrays.
const values = [1, , 3, [4, , 6]];
console.log(values.flat()); // [1, 3, 4, 6]This usually does not matter in normal arrays.
But it is another reason to avoid creating sparse arrays intentionally.
The flatMap Method
The .flatMap() method combines two steps:
- Map each item to a new value.
- Flatten the result one level.
This:
array.flatMap(callback);is similar to:
array.map(callback).flat();But flatMap is more direct when you know you need both steps.
Basic flatMap Example
Suppose each sentence should become words.
const sentences = ["hello world", "learn javascript"];
const words = sentences.flatMap((sentence) => {
return sentence.split(" ");
});
console.log(words); // ["hello", "world", "learn", "javascript"]Here is what happens:
First, map would produce:
[
["hello", "world"],
["learn", "javascript"]
]Then flat would turn it into:
["hello", "world", "learn", "javascript"]flatMap does both in one method.
map Plus flat
This code:
const words = sentences
.map((sentence) => sentence.split(" "))
.flat();produces the same result as:
const words = sentences.flatMap((sentence) => sentence.split(" "));Use flatMap when:
- each input item becomes an array
- you want one combined result array
- you only need to flatten one level
flatMap Flattens One Level Only
flatMap only flattens one level.
const values = [1, 2];
const result = values.flatMap((value) => {
return [[value, value * 2]];
});
console.log(result); // [[1, 2], [2, 4]]The callback returns nested arrays like:
[[1, 2]]flatMap flattens one level, so one level of nesting remains.
If you need deeper flattening, use map() and then flat(depth).
const result = values
.map((value) => [[value, value * 2]])
.flat(2);
console.log(result); // [1, 2, 2, 4]Returning One, Many, or No Items
flatMap is useful because each input item can produce:
- one output item
- multiple output items
- zero output items
One item:
const numbers = [1, 2, 3];
const doubled = numbers.flatMap((number) => {
return [number * 2];
});
console.log(doubled); // [2, 4, 6]Multiple items:
const numbers = [1, 2, 3];
const pairs = numbers.flatMap((number) => {
return [number, number * 2];
});
console.log(pairs); // [1, 2, 2, 4, 3, 6]No items:
const numbers = [1, 2, 3, 4];
const evenDoubles = numbers.flatMap((number) => {
if (number % 2 === 0) {
return [number * 2];
}
return [];
});
console.log(evenDoubles); // [4, 8]This can act like filtering and mapping in one step.
But use it only when it stays readable.
flatMap for Tags
Imagine each article has tags.
const articles = [
{ title: "Intro to JS", tags: ["javascript", "basics"] },
{ title: "Array Methods", tags: ["javascript", "arrays"] },
{ title: "CSS Layout", tags: ["css", "layout"] },
];
const allTags = articles.flatMap((article) => {
return article.tags;
});
console.log(allTags);Output:
["javascript", "basics", "javascript", "arrays", "css", "layout"]Each article maps to an array of tags.
flatMap combines all those tag arrays into one array.
Removing Duplicates After flatMap
If you want unique tags, combine flatMap with Set.
const uniqueTags = [...new Set(allTags)];
console.log(uniqueTags); // ["javascript", "basics", "arrays", "css", "layout"]This is a common pattern:
const uniqueTags = [
...new Set(
articles.flatMap((article) => article.tags)
),
];It:
- extracts all tag arrays
- flattens them into one array
- removes duplicates with
Set
flat vs flatMap
Use flat when the array is already nested.
const nested = [[1, 2], [3, 4]];
const result = nested.flat();
console.log(result); // [1, 2, 3, 4]Use flatMap when you need to transform each item and flatten the result.
const sentences = ["hello world", "learn js"];
const words = sentences.flatMap((sentence) => sentence.split(" "));
console.log(words); // ["hello", "world", "learn", "js"]Comparison:
| Method | Use when | Depth |
|---|---|---|
flat |
You already have nested arrays | Configurable |
flatMap |
You need to map, then flatten | One level |
flatMap vs map
map keeps one output element per input element.
const sentences = ["hello world", "learn js"];
const mapped = sentences.map((sentence) => sentence.split(" "));
console.log(mapped);Output:
[
["hello", "world"],
["learn", "js"]
]flatMap combines those nested arrays:
const flatMapped = sentences.flatMap((sentence) => sentence.split(" "));
console.log(flatMapped); // ["hello", "world", "learn", "js"]Use map when you want to keep the nested structure.
Use flatMap when you want the combined result.
flat Does Not Deep Clone
Like slice and spread, flat creates a shallow result.
If the array contains objects, the objects are still shared references.
const nestedUsers = [
[{ name: "Alice" }],
[{ name: "Bob" }],
];
const users = nestedUsers.flat();
users[0].name = "Ava";
console.log(nestedUsers[0][0].name); // AvaThe outer array structure was flattened.
The objects inside were not deeply copied.
Best Practices
Use flat for already nested arrays:
const allItems = groupedItems.flat();Pass a depth when you need more than one level:
const result = nestedValues.flat(2);Use flatMap when each item turns into an array and you want one combined result:
const words = sentences.flatMap((sentence) => sentence.split(" "));Keep flatMap callbacks easy to read:
const tags = articles.flatMap((article) => article.tags);Use map().flat(depth) when you need a custom flattening depth:
const result = values.map(transform).flat(2);Avoid using flatMap just to look clever.
If filter().map() is clearer, use that.
Common Mistakes
Mistake 1: Expecting flat to Flatten All Levels by Default
const nested = [1, [2, [3, [4]]]];
console.log(nested.flat()); // [1, 2, [3, [4]]]By default, flat() flattens one level.
Use a depth:
console.log(nested.flat(3)); // [1, 2, 3, 4]Or:
console.log(nested.flat(Infinity)); // [1, 2, 3, 4]Mistake 2: Using flatMap When the Callback Does Not Return Arrays
const numbers = [1, 2, 3];
const doubled = numbers.flatMap((number) => number * 2);
console.log(doubled); // [2, 4, 6]This works, but map is clearer because no flattening is needed:
const doubled = numbers.map((number) => number * 2);Mistake 3: Expecting flatMap to Flatten Deeply
const values = [1, 2];
const result = values.flatMap((value) => [[value]]);
console.log(result); // [[1], [2]]flatMap flattens one level only.
Use map().flat(2) if you need deeper flattening.
Mistake 4: Forgetting That Objects Are Still Shared
const nestedUsers = [[{ name: "Alice" }]];
const users = nestedUsers.flat();
users[0].name = "Ava";
console.log(nestedUsers[0][0].name); // AvaFlattening does not deeply clone objects.
Quick Check
What does this return?
const values = [[1, 2], [3, 4]];
const result = values.flat();It returns:
[1, 2, 3, 4]What does this return?
const values = [1, [2, [3]]];
const result = values.flat();It returns:
[1, 2, [3]]flat() only flattens one level by default.
What does this return?
const sentences = ["hi there", "learn arrays"];
const words = sentences.flatMap((sentence) => sentence.split(" "));It returns:
["hi", "there", "learn", "arrays"]Each sentence becomes an array of words, and flatMap combines them.
Summary
flat and flatMap help you work with nested arrays.
flat()flattens nested arrays into a new array.flat()flattens one level by default.- Pass a depth like
flat(2)for deeper flattening. - Use
flat(Infinity)to flatten all levels. flatMap()maps each item and then flattens one level.flatMap()is similar tomap().flat().- Use
flatwhen the array is already nested. - Use
flatMapwhen each item becomes an array and you want one combined result. - Flattening is shallow; objects inside arrays are still shared references.