🥿

[JS / TS]flatMapっていつ使うん?

2022/12/17に公開約2,100字

はじめに

コードレビューをしてもらった時に、flatMap()ってこういう時に使えるのか!
っとなった時のメモ

flatMapとは?

flatMap メソッドは、map の後に深さ 1 の flat を呼び出すのと同じです。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap

flatMap() は上記の通り、map()flat()を組み合わせたメソッドです。
それぞれ軽く見てみると、

  • map()
    • 各要素に対して一度ずつ呼び出して処理
    • 処理結果を新しい配列として返却
  • flat()
    • 配列の要素を指定した深さ(ネスト)で結合
    • 結合した新しい配列を返却。

むむ?
map()はさておき、flat() がわかりづらい、、
実装例を見てみると

const arr1 = [0, 1, 2, [3, 4]];

console.log(arr1.flat());
// expected output: [0, 1, 2, 3, 4]

のように、配列のネスト具合を浅くするメソッドのようです。

つまり、上記をまとめると

  • 配列の各要素に対して処理して
  • 処理結果のネストを浅くした配列を返す

のがflatMap()ということになります。

配列のネストを浅くする、、?
使い所がパッとイメージできないです、、

こんな時に使えるかも!

前述の通り、(私の場合は)flatMap()の使い所がイマイチ掴めず、後回しの対象になってました。
が、レビューで頂いた実装を見て、
「flatMapさんバカにしてすみません、、」
となりました。

要素の抽出

flatMap()さんは、配列やオブジェクトの要素を抽出する時に、非常に便利に使えるメソッドです。
下記の例では、stringまたはnumber型の配列から、number型の値のみ抽出しています。

type HogeType = (string | number)[];

const hoge: HogeType = ["aaa", "bbb", 111, 222];

const mapResult = hoge.map((v) => (typeof v === "number" ? v : [])); // [[], [], 111, 222]
const flatMapResult = hoge.flatMap((v) => (typeof v === "number" ? v : [])); // [111, 222]

オブジェクトの場合は下記の感じです。

type HogeType = {
  a: string;
  b: string;
  c: number;
  d: number;
};
const hoge: HogeType = { a: "aaa", b: "bbb", c: 111, d: 222 };

const mapResult = Object.values(hoge).map((v) => (typeof v === "number" ? v : [])); // [[], [], 111, 222]
const flatMapResut = Object.values(hoge).flatMap((v) => (typeof v === "number" ? v : [])); // [111, 222]

ポイントは、条件に当てはまらない場合は[]を返すところです。
これにより、.map()[[], [], 111, 222] となったものが、
.flat()の処理で空配列が削除され[111, 222]が抽出される仕組みです。

まとめ

  • .flatMap().map() + .flat()した処理である
  • .flatMap()は、条件に当てはまらない場合は[]を返すことで、値の抽出ができる

具体的に「こういう場面で使える!」という選択肢が増えると、より面白さを感じられますね。
これだからプログラミングはやめられないってばよ。。

※他にもこんな使い方ができるよってものがありましたら、コメント頂けると幸いです。

参考

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap
https://qiita.com/NeGI1009/items/4befe4695a4712d96d56
https://zenn.dev/yarnaimo/articles/66e9102a79c0896b4204

Discussion

ログインするとコメントできます