Elixirでの内包表記の勉強の折、リストに繰り返し処理が簡潔に書けて、良いなと思い覚書を残しました。
for
とgeneratorで書く。generatorとはx <- list
のところ。
まずは単純な例から
iex(3)> list = [0,1,1,2,3,5,8]
[0, 1, 1, 2, 3, 5, 8]
iex(4)> for x <- list, do: x * 100
[0, 100, 100, 200, 300, 500, 800]
iex(5)> seq = for x <- 1..50, do: x
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
43, 44, 45, 46, 47, 48, 49, 50]
generatorのところでパターンマッチを使って書けるようになっている。
iex(12)> for {:one, val} <- [one: 1, two: 2], do: val
[1]
特定の条件に一致したものだけフィルタリングしたい場合は以下のように書く。
list = for x <- 1..100, rem(x, 2) == 0, do: x
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
43, 44, 45, 46, 47, 48, 49, 50, ...]
generatorが複数の場合は、以下のようになる。
iex(9)> for x <- [1,2], y <- [3,4,5], do: {x,y}
[{1, 3}, {1, 4}, {1, 5}, {2, 3}, {2, 4}, {2, 5}]
要素数は、各generatorの要素数の積。入れ子になると理解しておく
フィルタの条件も複数記述することができる。この場合記述した条件をすべて満たす要素からリストが生成される。
iex(11)> for x <- [1,2], y<- [3,4,5], rem(x,2) == 0, rem(y,2) == 0, do: {x,y}
[{2, 4}]
これまでの例から、内包表記はリスト形式で値を返している。into:
を指定することでリスト以外も生成することができる。
例えば、以下はMapを返す。
iex(15)> for x <- [1,2], y<- [3,4,5], rem(x,2)==0, rem(y,2)==0, into: %{}, do: {x, y}
%{2 => 4}
内包表記は以下のリンクや書籍の解説を参考にしました。
Elixir School 13.内包表記
プログラミングElixir