If you've been writing JavaScript for a while, you've probably used map()
countless times. But have you ever run into a situation where map()
left you with nested arrays that you needed to flatten? That's where flatMap()
comes to the rescue.
Let's dive into the differences between these two array methods and when to use each one.
The Basics: What Does map() Do?
The map()
method creates a new array by calling a function on every element of the original array. It's a one-to-one transformation - each element in the input array produces exactly one element in the output array.
const numbers = [1, 2, 3, 4];
const doubled = numbers.map(x => x * 2);
console.log(doubled); // [2, 4, 6, 8]
Simple enough, right? But what happens when your mapping function returns an array?
const words = ['hello', 'world'];
const letters = words.map(word => word.split(''));
console.log(letters); // [['h','e','l','l','o'], ['w','o','r','l','d']]
Oops! We got an array of arrays. This is where things get interesting.
Enter flatMap(): The Flattening Hero
flatMap()
is like map()
with a superpower - it automatically flattens the result by one level. Think of it as map()
followed by flat(1)
.
const words = ['hello', 'world'];
const letters = words.flatMap(word => word.split(''));
console.log(letters); // ['h','e','l','l','o','w','o','r','l','d']
Much better! All the letters are in a single flat array.
The Key Difference
The fundamental difference is this:
map()
always returns an array with the same length as the input
flatMap()
can return an array with a different length because it flattens one level
Here's a side-by-side comparison:
const sentences = ['Hello world', 'How are you'];
// Using map()
const wordsNested = sentences.map(sentence => sentence.split(' '));
console.log(wordsNested);
// [['Hello', 'world'], ['How', 'are', 'you']]
// Using flatMap()
const wordsFlat = sentences.flatMap(sentence => sentence.split(' '));
console.log(wordsFlat);
// ['Hello', 'world', 'How', 'are', 'you']
Real-World Examples
Example 1: Processing User Data
Let's say you have users with multiple email addresses:
const users = [
{ name: 'Alice', emails: ['alice@work.com', 'alice@personal.com'] },
{ name: 'Bob', emails: ['bob@company.com'] },
{ name: 'Charlie', emails: ['charlie@startup.com', 'charlie@gmail.com', 'charlie@yahoo.com'] }
];
// Get all email addresses in one flat array
const allEmails = users.flatMap(user => user.emails);
console.log(allEmails);
// ['alice@work.com', 'alice@personal.com', 'bob@company.com', 'charlie@startup.com', 'charlie@gmail.com', 'charlie@yahoo.com']
With map()
, you'd get nested arrays and need an extra step to flatten them.
Example 2: Filtering and Mapping Combined
flatMap()
is also great when you want to filter out some elements while transforming others:
const numbers = [1, 2, 3, 4, 5, 6];
// Get only even numbers, but double them
const evenDoubled = numbers.flatMap(n =>
n % 2 === 0 ? [n * 2] : []
);
console.log(evenDoubled); // [4, 8, 12]
Notice how we return an empty array []
for odd numbers? flatMap()
flattens these away, effectively filtering them out.
const blogPosts = [
{ title: 'JS Tips', tags: ['javascript', 'programming'] },
{ title: 'CSS Grid', tags: ['css', 'layout', 'design'] },
{ title: 'Node.js Guide', tags: ['nodejs', 'backend'] }
];
// Get all unique tags
const allTags = [...new Set(blogPosts.flatMap(post => post.tags))];
console.log(allTags);
// ['javascript', 'programming', 'css', 'layout', 'design', 'nodejs', 'backend']
When to Use Which?
Use map()
when:
- You want a one-to-one transformation
- The result should have the same length as the input
- You're not dealing with nested arrays
Use flatMap()
when:
- Your transformation returns arrays that you want flattened
- You want to filter out elements (by returning empty arrays)
- You're extracting multiple values from each element
flatMap()
is slightly more expensive than map()
because it does extra work to flatten the result. If you don't need flattening, stick with map()
. But if you find yourself doing array.map(...).flat()
, replace it with flatMap()
for better performance and cleaner code.
Browser Support
flatMap()
is well-supported in modern browsers (ES2019/ES10). It's available in:
- Chrome 69+
- Firefox 62+
- Safari 12+
- Node.js 11+
For older environments, you can use a polyfill or stick with map().flat()
.
Wrapping Up
Both map()
and flatMap()
are essential tools in your JavaScript toolkit. map()
is your go-to for simple transformations, while flatMap()
shines when you need to flatten nested results or combine mapping with filtering.
The next time you find yourself with nested arrays after a map()
operation, remember flatMap()
- it might be exactly what you need to keep your code clean and efficient.