1. ホーム
  2. javascript

[解決済み] なぜjavascriptにはArray.prototype.flatMapがないのですか?

2023-04-04 07:48:30

質問

flatMap はコレクションで非常に便利ですが、javascriptはそれを提供しません。 Array.prototype.map . なぜでしょうか?

をエミュレートする方法はありますか? flatMap を定義することなく、javascript で簡単かつ効率的に flatMap を手動で定義することなく、簡単かつ効率的な方法で?

どのように解決する?

更新しました。 Array.prototype.flatMap ES2019 に取り込まれた

多くの環境で広くサポートされています。以下のスニペットを使って、あなたのブラウザで動くかどうか確認してみてください。

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((r, x) => r.concat(f(x)), [])

const xs = [1,2,3]

console.log(flatMap(x => [x-1, x, x+1], xs))

を拡張したい場合は Array.prototype を拡張したいのであれば、何もあなたを止めることはありません。

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