In JavaScript, `flatMap()` is an array method that combines the functionality of `map()` followed by `flat(1)`. It first applies a mapping function to each element of an array, creating a new array of mapped elements. Then, it flattens the result into a new array, but only up to a depth of 1 (one level).
Essentially, `flatMap()` allows you to perform a transformation on each element of an array and then concatenate all the resulting arrays (or iterables) into a single, new array.
## How flatMap() Works
The `flatMap()` method works in two main steps:
1. **Map:** It iterates over each element in the original array and calls a provided callback function for each element. This callback function returns a new value or, crucially, an *array* of values.
2. **Flatten:** After the mapping step, `flatMap()` takes the array of results produced by the callback and flattens it by one level. This means if your callback returned arrays, the elements of those inner arrays are merged directly into the final output array.
### The Power to Modify Item Count
A significant advantage of `flatMap()` over `map()` is its ability to *modify the number of items* in the resulting array compared to the original array. Unlike `map()`, which always produces a one-to-one correspondence between input and output items, `flatMap()` allows you to:
* Return an empty array (`[]`) from the callback for an element you want to **remove** from the final result.
* Return a single-element array (`[value]`) for an element that maps to just one item.
* Return a multi-element array (`[value1, value2, ...]`) for an element that maps to **multiple items**.
As highlighted in the reference, `flatMap` **can be used as a way to add and remove items (modify the number of items) during a map**. In other words, **it allows you to map many items to many items (by handling each input item separately)**. In this sense, it **works like the opposite of filter**, which only removes items, whereas `flatMap` can both add and remove items from the output relative to the input.
### Comparing map(), filter(), and flatMap()
Here's a quick comparison of how these common array methods affect the number of items:
| Method | Purpose | Item Count Transformation |
| :--------- | :---------------------------------------- | :------------------------ |
| `map()` | Transform each element | One-to-one (count stays same) |
| `filter()` | Select elements based on a condition | Many-to-one (count decreases or stays same) |
| `flatMap()`| Map *and* flatten (depth 1) | Many-to-many (count can increase, decrease, or stay same) |
## flatMap() Syntax
The basic syntax is straightforward:
```javascript
arr.flatMap(callback(currentValue[, index[, array]])[, thisArg])
callback
: A function that produces an element of the new array, called for each element in the original array. It takescurrentValue
, optionalindex
, and optionalarray
as arguments. It should return a value or an array of values.thisArg
(optional): Value to use asthis
when executing the callback.
JavaScript flatMap() Example
Let's see flatMap()
in action. Suppose you have an array of words and you want to split each word into its individual letters, creating a single array of all letters.
const words = ["Hello", "World"];
// Using map() and flat()
const lettersMapped = words.map(word => word.split(''));
// Result: [["H", "e", "l", "l", "o"], ["W", "o", "r", "l", "d"]] (Array of arrays)
const allLetters = lettersMapped.flat();
// Result: ["H", "e", "l", "l", "o", "W", "o", "r", "l", "d"] (Flattened array)
// Using flatMap() - achieves the same result in one step
const allLettersFlatMapped = words.flatMap(word => word.split(''));
// Result: ["H", "e", "l", "l", "o", "W", "o", "r", "l", "d"] (Flattened array)
console.log(allLettersFlatMapped);
// Output: [ 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' ]
Here's an example demonstrating how flatMap
can add or remove items:
const numbers = [1, 2, 3];
// flatMap to duplicate odd numbers, remove even numbers
const transformedNumbers = numbers.flatMap(num => {
if (num % 2 !== 0) {
// Return an array with the number duplicated (adds items)
return [num, num];
} else {
// Return an empty array (removes the item)
return [];
}
});
console.log(transformedNumbers);
// Output: [ 1, 1, 3, 3 ]
// Input: [1, 2, 3] -> Output: [1, 1, 3, 3] (Modified count and items)
In this example:
- For
1
, the callback returns[1, 1]
, adding an item. - For
2
, the callback returns[]
, removing the item. - For
3
, the callback returns[3, 3]
, adding an item.
The final array[1, 1, 3, 3]
shows the effect of adding and removing items during the mapping process.
Why Use flatMap()?
flatMap()
is useful when you need to:
- Transform each element and then combine the results into a single array, especially when the transformation might result in multiple items or no items for a single input item.
- Improve code readability by combining a common
map()
followed byflat(1)
operation into a single method call. - Efficiently handle scenarios where you are mapping "one-to-many" or need to conditionally include/exclude items based on the mapping logic, acting as a more flexible alternative to just
map
orfilter
.
It's a powerful tool for data manipulation in JavaScript arrays, offering a concise way to perform complex transformations and restructuring.