Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

Elixir~Enum.mapとfilterの複合〜

いままでわからなかったこと

Enum.mapやFilterやパイプライン演算子はElixirドキュメントの写経で出てきた。
しかしそれを自分の頭で考えてコードを組み立てることができない。赤子のようだ!

本題

設問1
最初に[3, 9, 27]のリストをもとにして各要素を3倍したあとで、30より大きい要素を出力する

iex> [3, 9, 27, 81] |> Enum.map(& &1 * 3) |> Enum.filter(& &1 >= 30)
[81, 243]

mapでの乗法とfilterでのソートも、パイプライン演算子を数珠つなぎにすることで可能になっています。

設問2
1から10までの整数のリストをもとにして、各要素を2倍したあとで10より小さな値を抜き出してさらに各要素を二乗して出力する

iex> 1..10 |> Enum.map(& &1 *2) |> Enum.filter(& &1 <= 10) |> IO.inspect |> Enum.map(& &1 * &1)
[2, 4, 6, 8, 10]
[4, 16, 36, 64, 100]

途中でパイプライン演算子を挟みデバッグに使うIO.inspectを入れて[2,4,6,8,10]の途中経過を表示させています。

パイプライン演算子について

設問2をシンセサイザーに例えてみましょう。IO.inspectはここでは省略します。2段目のmapと3段目のfilterを入れ替えて結果を見てみましょう。

iex> 1..10 |> Enum.map(& &1 *2) |> Enum.filter(& &1 <= 10) |>  Enum.map(& &1 * &1)    
[4, 16, 36, 64, 100]

iex> 1..10 |> Enum.map(& &1 *2) |>  Enum.map(& &1 * &1) |> Enum.filter(& &1 <= 10)
[4]

驚くべきなのか当然と片付けるべきかわからないのですがmapとfilterの内容を入れ替えると結果が変わりました。
これは、左辺のリストをエレキギターのコイルやシンセサイザーのオシレーターとしたら、のちにかけるフィルター(filter)やオーバードライブ(map)の順番によっていかようにも出音が変わることと共通しています。

ここまでの気づき

このエントリ自体はなんてことのないEnumの四則演算のパイプライン演算子ごとの順番入れ替えによって結果が変わることを図示したものですが、わたし自身音楽家であることもあり、"オシレーターとフィルターとLFOの順番違ったら音違うじゃん!それとElixirも一緒!って言われたら納得するな"と思い記事をしたためた次第です。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
1
Help us understand the problem. What are the problem?