Something that people may not see immediately is that flatMap is more general than map <i>and</i> filter. Say, for a contrived example, that you'd like to filter out the even numbers in an array, and then double the odd numbers that remain. Instead of:<p><pre><code> [1, 2, 3, 4, 5].filter(n => n % 2 === 1).map(n => n * 2)
</code></pre>
You can do:<p><pre><code> [1, 2, 3, 4, 5].flatMap(n => n % 2 === 1 ? [n * 2] : [])
</code></pre>
Again, this is a contrived example, but I think it's interesting since the generality is not obvious (to me)
I've made it a habit to check Mozilla's JS docs once in a while for functions like Flat() and FlatMap(). Sometimes if I find myself reaching for underscore/lodash, I'll check Mozilla docs first to see if there's some new function that can let me omit using lodash.<p>I'm often delighted to find new convenience functions I can just use without adding another dependable.
I've always found `flatMap` to be interesting because it feels like a convenience function, combining .map(fn).flat() into one function. It's interesting because JS doesn't really have a lot of convenience functions that are this shallow (ie. that provide just minimal cleanup compared to the functions they're wrapping).<p>Is there some specific reason that `flatMap` made the cut?
I have very little experience with arrays in JS, but I always have a nagging feeling that, if my algorithm needs me to flatten an array, then there is something wrong with the data structures I am using.<p>Example in the article is meaningless to me:<p><pre><code> array.map(x => [x \* 2]);
// [[2], [4], [6], [8]]
array.flatMap(x => [x * 2]);
// [2, 4, 6, 8]
</code></pre>
because the right way would be array.map(x => x *2); anyway.<p>What am I missing? What is a realistic scenario where an array needs to be flattened?
I'm glad JS is adding these methods to Array. It would be nice if iterables had similar methods for working with lazy sequences, similar to Rust, but this isn't practical since "iterable" is a protocol. Array can do it because it's a class. Perhaps JS could also adopt something similar to Rust's traits, such that implementing the protocol would make a set of related methods callable on that object.
In J this is just , (ravel) <a href="https://code.jsoftware.com/wiki/Vocabulary/comma" rel="nofollow">https://code.jsoftware.com/wiki/Vocabulary/comma</a>
This stirs up some memories of Perl, where flattening arrays/lists is the default, and you need explicit references to have nested arrays or hash tables. I remember it used to be a kind of foot-seeking gun for newbies, but I never ran into trouble with it once I understood references (which isn't super hard).