flatMap
is incredibly useful on collections, but javascript does not provide one while having Array.prototype.map
. Why?
Is there any way to emulate flatMap
in javascript in both easy and efficient way w/o defining flatMap
manually?
The array. flatMap() is an inbuilt function in JavaScript which is used to flatten the input array element into a new array. This method first of all map every element with the help of mapping function, then flattens the input array element into a new array.
So what's the exact difference between map and flatMap: map transforms items emitted by an Observable by applying a function to each item whereas flatmap: Applies a specified function to each emitted item and this function in turn returns an Observable for each item.
flat() method to flat an array with the nested arrays. Use the depth argument to specify how deep the nested arrays should be flattened. The depth is 1 by default. The flat() also removes the holes in the array with empty slots.
Update: Array.prototype.flatMap
made it into ES2019
It is widely supported in many environments. See if it works in your browser using this snippet below -
const data = [ 1, 2, 3, 4 ] console.log(data.flatMap(x => Array(x).fill(x))) // [ 1, 2, 2, 3, 3, 3, 4, 4, 4, 4 ]
"Why no Array.prototype.flatMap in javascript?"
Because programming isn't magic and every language doesn't have features/primitives that every other language has. What matters is JavaScript gives you the ability to define it on your own -
const concat = (x,y) => x.concat(y) const flatMap = (f,xs) => xs.map(f).reduce(concat, []) const xs = [1,2,3] console.log(flatMap(x => [x-1, x, x+1], xs))
Or a rewrite that collapses the two loops into one -
const flatMap = (f, xs) => xs.reduce((r, x) => r.concat(f(x)), []) const xs = [1,2,3] console.log(flatMap(x => [x-1, x, x+1], xs))
If you want it to extend the Array.prototype
, nothing is stopping you -
if (!Array.prototype.flatMap) { function flatMap (f, ctx) { return this.reduce ( (r, x, i, a) => r.concat(f.call(ctx, x, i, a)) , [] ) } Array.prototype.flatMap = flatMap } const ranks = [ 'J', 'Q', 'K', 'A' ] const suits = [ '♡', '♢', '♤', '♧' ] const result = ranks.flatMap(r => suits.flatMap(s => [[r, s]] ) ) console.log(JSON.stringify(result)) // [ ['J','♡'], ['J','♢'], ['J','♤'], ['J','♧'] // , ['Q','♡'], ['Q','♢'], ['Q','♤'], ['Q','♧'] // , ['K','♡'], ['K','♢'], ['K','♤'], ['K','♧'] // , ['A','♡'], ['A','♢'], ['A','♤'], ['A','♧'] // ]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With