224
89

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-04-08

前回の記事、
ワイ「なに!?型のズレを吸収できるやと!?」
の続きやで!

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

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

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

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

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

ハスケル子「はあ」

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

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

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

ハスケル子「それは?」

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

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

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

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

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

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

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

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

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

ワイ「それがな・・・」

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

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

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

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

ハスケル子「可能ですが?

ワイ「まじかいな」

ハスケル子「このまえ使ったflat()を使うんですよ!」

ワイ「ほお」

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

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

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

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

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

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

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

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

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

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

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

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

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

ワイ「おお・・・!」
ワイ「これがこのまえ言うてたflatMap()かいな」
ワイ「こんな都合のいいメソッドが・・・!?」
ワイ「まさに、ワイの有給を増やすためのメソッドやないかい・・・」

社長「(いや違うやろ・・・)」

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

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

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

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

JavaScript
name => [name, name, name]

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

JavaScript
name => ...[name, name, name]

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

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

ワイ「おお・・・!」
ワイ「前回ハスケル子ちゃんが言うてた・・・」

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

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

ハスケル子「はい!」

ワイ「確かに楽しいな!」

ハスケル子「はい!」

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

まとめ

  • いっぱい休めた。

社長「いやそれがまとめかい!

まとめ(やり直し)

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

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

ハスケル子「はい!」

社長「(有給やなくて、悠久の休み1をくれたろか・・・)」

〜おしまい〜

続編もよろしくやで!

4歳娘「パパ、そんなときはクロージャが役に立つんじゃない?」

参考文献

注意

  • もちろんIEでは使えへんから、Babelとか使ってな!(定期)
  • ほんまに改ざんとかしたらアカンで!
  1. 悠久の休み・・・解雇のことです。

224
89
10

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
224
89

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?