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','♧']
// ]