flatMap
はコレクションで非常に便利ですが、javascriptはArray.prototype.map
を持っている間は提供しません。どうして?
flatMap
を手動で定義せずに、簡単で効率的な方法でJavaScriptでflatMap
をエミュレートする方法はありますか?
更新:Array.prototype.flatMap
は、ネイティブECMAScriptへの道を進んでいます。現在Stage 4です。
多くの環境で広くサポートされています。以下のスニペットを使用して、ブラウザで機能するかどうかを確認してください-
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 ]
JavascriptにArray.prototype.flatMapがないのはなぜですか?
プログラミングは魔法ではなく、すべての言語には他のすべての言語が持っている機能/プリミティブがないためです
重要なのは
JavaScriptを使用すると、独自に定義することができます
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))
または、2つのループを1つにまとめる書き換え
const flatMap = (f,xs) =>
xs.reduce((acc,x) =>
acc.concat(f(x)), [])
const xs = [1,2,3]
console.log(flatMap(x => [x-1, x, x+1], xs))
Array.prototype
で必要な場合は、何もあなたを止めません
const concat = (x,y) =>
x.concat(y)
const flatMap = (f,xs) =>
xs.map(f).reduce(concat, [])
Array.prototype.flatMap = function(f) {
return flatMap(f,this)
}
const xs = [1,2,3]
console.log(xs.flatMap(x => [x-1, x, x+1]))
flatMap
は、ES2019(ES10)の一部としてTC39によって承認されています。次のように使用できます。
[1, 3].flatMap(x => [x, x + 1]) // > [1, 2, 3, 4]
メソッドの実装は次のとおりです。
const flatMap = (f, arr) => arr.reduce((x, y) => [...x, ...f(y)], [])
自分で定義したくないと言っていたことは知っていますが、 この実装 は非常に簡単な定義です。
同じgithubページからもこれがあります:
以下は、renaudtertraisに似たes6 spreadを使用した少し短い方法ですが、es6を使用し、プロトタイプに追加しません。
var flatMap = (a, cb) => [].concat(...a.map(cb))
const s = (v) => v.split(',')
const arr = ['cat,dog', 'fish,bird']
flatMap(arr, s)
これらのいずれかが役立ちますか?
(@ftorのおかげで)後者の「ソリューション」は、本当に大きな(たとえば300k要素)配列a
で呼び出された場合、「最大呼び出しスタックサイズを超過」することに注意する必要があります。
Lodash はflatmap関数を提供します。これは私にとって、ネイティブに提供するJavascriptと実質的に同等です。 Lodashを使用していない場合、ES6のArray.reduce()
メソッドを使用しても同じ結果を得ることができますが、個別のステップでマッピングして平坦化する必要があります。
以下は、整数のリストをマッピングし、オッズのみを返す各メソッドの例です。
Lodash:
_.flatMap([1,2,3,4,5], i => i%2 !== 0 ? [i] : [])
ES6 Reduce:
[1,2,3,4,5].map(i => i%2 !== 0 ? [i] : []).reduce( (a,b) => a.concat(b), [] )
かなり簡潔なアプローチの1つは、Array#concat.apply
を使用することです。
const flatMap = (arr, f) => [].concat.apply([], arr.map(f))
console.log(flatMap([1, 2, 3], el => [el, el * el]));
JavascriptにflatMap()
が追加されました!そして、それはサポートされています かなりうまく
FlatMap()メソッドは、まずマッピング関数を使用して各要素をマッピングし、次に結果を新しい配列にフラット化します。 map()の後に深さ1のflat()が続くのと同じです。
const dublicate = x => [x, x];
console.log([1, 2, 3].flatMap(dublicate))