ワイ「なに！？flatMap()で有給取り放題やと！？」

前回の記事、
[**ワイ「なに！？型のズレを吸収できるやと！？」**](https://qiita.com/Yametaro/items/af7dde38c6523dba110c)
の続きやで！

## ある日、コソコソと配列をいじるワイ

ワイ「うーん、これではまた駄目や・・・」

ハスケル子「やめ太郎さん、さっきから何か配列いじってますけど」
ハスケル子「それ何の配列なんですか？」

```javascript:JavaScript
let vacationOrderList =
    ["ハリー先輩", "カリポリ君", "やめ太郎", "ハリー先輩", "カリポリ君", "やめ太郎", ...];
```

ワイ「↑これはな、ワイのチームのみんなの**有給休暇の順番**や」
ワイ「弊社は**有給取り放題**やから」
ワイ「チームのみんなで順番に有給休暇を取得しまひょ〜、いうて」
ワイ「有給の順番表を表示するための**簡単なWebページ**を作ったんや」

ハスケル子「はあ」

ワイ「さっきの配列を元に、画面上に**有給の順番リスト**を表示して」
ワイ「そのページを見ながら、みんなで順番に有給を取っていくんや」

ハスケル子「はい」
ハスケル子「それで、やめ太郎さんはどうして」
ハスケル子「その有給休暇の配列をいじってたんですか？」

ワイ「そ、それは・・・」

ハスケル子「それは？」

ワイ「・・・たいんや・・・」

ハスケル子「何ですか？**ハッキリ言ってください**」

ワイ「・・・ワイの休みを・・・増やしたいんや・・・」

ハスケル子「そうですか・・・」

ワイ「せやから、有給の順番リストが画面に表示される前に」
ワイ「**ちょっと処理を挟んで**、ワイの休みを増やそうとしてたんや」

ハスケル子「・・・」
ハスケル子「それで、何がうまく行かないんですか？」

ワイ「聞いてくれるか？」
ワイ「とりあえず、有給の順番を改ざんしようと思って`map()`メソッドを実行したんや」


```javascript:JavaScript
vacationOrderList =
    vacationOrderList
        .map(name => name === "カリポリ君"? "やめ太郎": name);
```

ハスケル子「カリポリ君の休みを全て、やめ太郎さんの休みに書き換えたわけですね」
ハスケル子「完璧な処理じゃないですか」
ハスケル子「何が駄目だったんですか？」

ワイ「それがな・・・」

> カリポリ君「あれ？」
カリポリ君「オレの休み、**1日も無くなってんだけど**」
カリポリ君「代わりに、やめ太郎の休み**メッチャ増えてんだけど**」


ワイ「・・・ってな感じで、バレてもうたんや・・・」

ハスケル子「さすがカリポリさん、鋭いですね」

ワイ「誰かの休みを**丸ごと**ワイの休みに置き換えるような」
ワイ「そんな**ダイナミック**な処理をするとバレてしまうみたいなんや」
ワイ「せやから、もうちょっと**自然にワイの休みを増やしたい**んや・・・」
ワイ「そんなこと、不可能なんかな・・・」

ハスケル子「**可能ですが？**」

ワイ「まじかいな」

ハスケル子「[**このまえ**](https://qiita.com/Yametaro/items/af7dde38c6523dba110c)使った`flat()`を使うんですよ！」

ワイ「ほお」

ハスケル子「まず、イメージをお伝えするために」
ハスケル子「`map()`を使って書いてみますね」

```javascript:JavaScript
vacationOrderList =
    vacationOrderList
        .map(name => name === "やめ太郎"? [name, name, name]: name);
```

ワイ「**ファッ！？**」
ワイ「そんなことしたら、配列が↓こうなってしまうやないか！！！」

```javascript:JavaScript
["ハリー先輩", "カリポリ君", ["やめ太郎", "やめ太郎", "やめ太郎"], "ハリー先輩", "カリポリ君", ["やめ太郎", "やめ太郎", "やめ太郎"], ...]
```

ワイ「ワイのところだけ**配列**になってしまうから」
ワイ「**即バレ**やでこんなもん！」

ハスケル子「そこで`flat()`を使うんです」

```javascript:JavaScript
vacationOrderList =
    vacationOrderList
        .map(name => name === "やめ太郎"? [name, name, name]: name)
        .flat();
```

ハスケル子「`flat()`は配列を**1階層フラットにしてくれる**ので」
ハスケル子「配列は↓こうなります」

```javascript:JavaScript
["ハリー先輩", "カリポリ君", "やめ太郎", "やめ太郎", "やめ太郎", "ハリー先輩", "カリポリ君", "やめ太郎", "やめ太郎", "やめ太郎", ...]
```

ワイ「うおお、自然や・・・！」
ワイ「限りなく自然や・・・！」

社長「（**いや不自然やろ**）」
社長「（**なんでお前の休みだけメッチャ増えてんねん・・・**）」

ハスケル子「しかも、`map()`して`flat()`している部分は」
ハスケル子「`flatMap()`メソッドでまとめられます」

```javascript:JavaScript
vacationOrderList =
    vacationOrderList
        .flatMap(name => name === "やめ太郎"? [name, name, name]: name);
```

ワイ「おお・・・！」
ワイ「これが[**このまえ**](https://qiita.com/Yametaro/items/af7dde38c6523dba110c)言うてた`flatMap()`かいな」
ワイ「こんな**都合のいい**メソッドが・・・！？」
ワイ「まさに、**ワイの有給を増やすための**メソッドやないかい・・・」

社長「（**いや違うやろ・・・**）」

ハスケル子「まあ、何でもいいんですけど」
ハスケル子「`map()`や`filter()`ではできない、**配列の要素を増やすような処理**を」
ハスケル子「条件に応じてできるのが、`flatMap()`の素敵なところですね」

ワイ「そうか」
ワイ「`map()`やと要素数は同じままやし」
ワイ「`filter()`やと要素数は減るだけやもんな」

ハスケル子「そうですね」

ワイ「つまり、`flatMap()`を使うと・・・」

```javascript:JavaScript
name => [name, name, name]
```

ワイ「↑こういう、戻り値として**配列を返す関数**を・・・」

```javascript:JavaScript
name => ...[name, name, name]
```

ワイ「↑こんな風に、**展開しながら返してくれる関数**に**変身させてくれる**・・・」
ワイ「そんなイメージで使えるな！」

ハスケル子「**関数を変身させる**・・・まさにそうですね」
ハスケル子「普通、関数の**戻り値は1つ**ですけど」
ハスケル子「`flatMap()`メソッドに渡されたコールバック関数は」
ハスケル子「複数の値を返せる、つまり**多値返却**ができる関数に**変身**します」

ワイ「おお・・・！」
ワイ「[**前回**](https://qiita.com/Yametaro/items/af7dde38c6523dba110c)ハスケル子ちゃんが言うてた・・・」

> ハスケル子「もっと楽しい、`flatMap()`なんていうメソッドもありますよ」
ハスケル子「`map()`して`flat()`してくれるやつです」
ハスケル子「まるで**関数が変身する**みたいですよ」

ワイ「・・・ていうのは**こういうこと**やったんやな！」

ハスケル子「はい！」

ワイ「確かに**楽しい**な！」

ハスケル子「はい！」

社長「（**いや休みが増えてテンション上がっとるだけやろ**）」

## まとめ
+ いっぱい休めた。

社長「**いやそれがまとめかい！**」

## まとめ（やり直し）
+ `map()`して`flat()`するなら`flatMap()`を使える。
+ `flatMap()`を使ったら、**配列の要素を増やす**ような処理ができた。
+ 普通の関数を、**多値返却ができる関数**に変身させてくれる感じだった。
+ 戻り値で**3つも有給を返せる**みたいで、楽しくなった。

ワイ「ありがとうな、ハスケル子ちゃん」
ワイ「いっぱい休んで、しっかりプログラミングの勉強さしてもらうわ！」

ハスケル子「はい！」

社長「（有給やなくて、**悠久の休み**[^1]をくれたろか・・・）」

**〜おしまい〜**

## 続編もよろしくやで！

→[**4歳娘「パパ、そんなときはクロージャが役に立つんじゃない？」**](https://qiita.com/Yametaro/items/7a4521e23520947cc43e)

## 参考文献
+ [Array.prototype.flatMap() - MDN - Mozilla](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap)

## 注意

+ **もちろんIEでは使えへんから、Babelとか使ってな！**（定期）
+ **ほんまに改ざんとかしたらアカンで！**

[^1]: **悠久の休み**・・・**解雇**のことです。