When working with arrays, developers often use Array.filter().map()
to transform data. But did you know Array.flatMap()
can achieve the same result in a single step? Let’s explore when to use each.
Old Approach with 2 iteration: filter().map()
const persons = [
{ name: "Raja", age: 36 },
{ name: "Jaganathan", age: 65 },
{ name: "Kumar", age: 50 }
];
const result = persons.filter(p => p.age > 60).map(p => p.name);
console.log(result); // ["Jaganathan"]
Here, .filter()
first selects the matching objects, and then .map() extracts names. Though it involves two loops, modern JavaScript engines optimize it well, making it faster in many cases.
New Approach with 1 iteration: flatMap()
const result = persons.flatMap(({ age, name }) => age > 60 ? name : []);
console.log(result); // ["Jaganathan"]
With flatMap()
, we combine filtering and mapping in one pass, making the code more concise. However, performance may slightly drop because flatMap()
internally flattens arrays, adding overhead.
Performance Comparison
Multiple approaches have been tested on jsperf.app. Thanks @miketalbot and @webjose.
🔹 flatMap() vs filter().map() – There’s no clear winner, but flatMap() shows a slight performance advantage in some cases.
When to Use Each
✅ Use filter().map() when clarity and semantic intent are important.
✅ Use flatMap() when reducing iterations and simplifying code structure matters more than micro-optimizations.
Happy Coding! 😊
Top comments (13)
Is it more readable though? I'm not sure about that.
Anyway,
flatMap
can be made to perform faster than.filter
then.map
if you are more careful with the array construction:name
in an arrayDoing this improves the performance, so it becomes the fastest method. However,
flatMap
does not tell me you are doing afilter
and amap
; it tells me you are dealing with arrays of arrays, so I find the intent of the code requires significant parsing, which is probably not worth the 5% speed improvement.Performance results: jsperf.app/baxase
Even more tests: Version 3
This one demonstrates that the encapsulation of code is rather costly. If this were C++ or a similar language, this would be an indication that the function needs to be inlined.
Anyway, this was fun. Thanks, Mike! I learned about this performance website because of your insightful comment.
Wow, yeah, that's the thing isn't it - 2x the speed if we just use a normal loop... That shocked me, so I tried it with an iterator loop rather than a for...of, and there's a new winner (for which I'm slightly shocked)!!!
Version 4
Also, damn good point about the encapsulation, that is odd...
Ok, this is fun.
Version 5
I have encapsulated the code in a reusable function as before, only with the winner that iterates over the index of the array.
Look at the differences. Here's a screenshot ran in MS Edge v133:
Label #1 is the fastest one, your proposal using the iterator, then there's #2 which is the original encapsulated one. 45% slower. Damn!! But #3 is the iterator version encapsulated and is only 5 or 8% slower. This tells me that there's something wrong in Chromium. It doesn't have much sense to me such big difference. But what do I know.
Anyway, notice how there might be a difference between using
++i
andi++
. In C/C++, overloading this operator tellls you something very interesting:++i
is more performant (in C++) becausei++
has to create a copy of itself to be used as return value. It might be true for JavaScript too.Wow, that is fascinating... You're right, some very unexpected behaviour that...
As always, Mike making sense. Thanks for the insightful post.
I made an edition to your performance test because I think we should never lose sight of what plain JS can do: Version 2 of performance tests
As expected, plain JS beats them all.
Agreed flatMap has different purpose and semantic too. just illustrate for different use case.I miss the point of the unwanted array creation.
This will be much simpler for readability
Nice post. Another alternative would be
reduce
, however it is questionable on how readable it is in comparison :)jsperf.app/baxase/6
Good one Raja. Thx for introducing a new method with detailed performance reasoning.
More readable? Not at all, IMO ...
Chaining steps is the essence of this approach, and "filter" followed by "map" expresses that approach and that thought process much more clearly ...
Array.flatMap() is a great alternative to filter().map() for simplifying code by combining filtering and mapping into one iteration. While filter().map() is clear and easy to understand, flatMap() can be more concise and reduce iterations. However, flatMap() can introduce slight performance overhead due to internal array flattening. Use filter().map() when clarity matters and flatMap() for optimizing iterations.
Also, for those in Riyadh, remember to check the Salah times!