Enum.fetch
Enum.fetch([2, 4, 6], 0)
{:ok, 2}
iex> Enum.fetch([2, 4, 6], -3)
{:ok, 2}
iex> Enum.fetch([2, 4, 6], 2)
{:ok, 6}
iex> Enum.fetch([2, 4, 6], 4)
:error
Enum.fetch([2, 4, 6, 8],3)
{:ok, 8}
これは簡単なようです。リストの引数に対して、ゼロから数えてn番目の値があればokとともに返す関数のようです。
Enum.find
Enum.find([2, 4, 6], fn x -> rem(x, 2) == 1 end)
nil
Enum.find([2, 4, 6], 0, fn x -> rem(x, 2) == 1 end)
0
Enum.find([2, 3, 4], fn x -> rem(x, 2) == 1 end)
3
こちらは第一引数のなかから2で割ってあまりが1になるという条件式にあてはまる数値を返すようです。ただ、1番目の式の結果がnil、2番目で0が挿入されていると結果が0になるところがやや引っかかるところです。
Enum.find_index
Enum.find_index([2, 4, 6], fn x -> rem(x, 2) == 1 end)
nil
Enum.find_index([2, 3, 4], fn x -> rem(x, 2) == 1 end)
1
こちらはEnum.findと似ていますが、第一引数のリストのなかから条件式にあてはまる要素の数を返している、、のかな?
Enum.find_value
Enum.find_value([2, 4, 6], fn x -> rem(x, 2) == 1 end)
nil
Enum.find_value([2, 3, 4], fn x -> rem(x, 2) == 1 end)
true
Enum.find_value([1, 2, 3], "no bools!", &is_boolean/1)
"no bools!
こちらも条件式に対して結果を返すもののようですが、条件式にあてはまるものがなければnil、ひとつでもあればtrueを返しているのでしょうか。
3番目の式に関してはわたしの知識では図りかねます。
Enum.flat_map
Enum.flat_map([:a, :b, :c], fn x -> [x, x] end)
[:a, :a, :b, :b, :c, :c]
Enum.flat_map([{1, 3}, {4, 6}], fn {x, y} -> x..y end)
[1, 2, 3, 4, 5, 6]
Enum.flat_map([:a, :b, :c], fn x -> [[x]] end)
[[:a], [:b], [:c]]
こちらはかなりお手上げに近いのですが、最後のendの前の[x,x]、x..y、[[x]]の違いに着目してみると、ある一定の法則が見いだせそうです。
Enum.flat_map_reduce
enumerable = 1..100
n = 3
Enum.flat_map_reduce(enumerable, 0, fn x, acc ->
if acc < n, do: {[x], acc + 1}, else: {:halt, acc}
end)
{[1, 2, 3], 3}
Enum.flat_map_reduce(1..5, 0, fn x, acc -> {[[x]], acc + x} end)
{[[1], [2], [3], [4], [5]], 15}
公式ドキュメント からの英文を転載しておきます。
Maps and reduces an enumerable, flattening the given results (only one level deep).
It expects an accumulator and a function that receives each enumerable item, and must return a tuple containing a new enumerable (often a list) with the new accumulator or a tuple with :halt as first element and the accumulator as second.
完全にお手上げです。現時点の知識では全くわかりません。
Enum.group_by
Enum.group_by(~w{ant buffalo cat dingo}, &String.length/1)
%{3 => ["ant", "cat"], 5 => ["dingo"], 7 => ["buffalo"]}
Enum.group_by(~w{ant buffalo cat dingo}, &String.length/1, &String.first/1)
%{3 => ["a", "c"], 5 => ["d"], 7 => ["b"]}
複雑ですが法則性が見えてきます。
最初の式では、それぞれ綴りの文字数ごとにソートして結果を返しています。
2番目の式では、&String.first/1が付与されているので、それぞれの綴りの文字数ごとに最初の一文字を返しているように思えます。
Enum.intersperse
Enum.intersperse([1, 2, 3], 0)
[1, 0, 2, 0, 3]
Enum.intersperse([1], 0)
[1]
Enum.intersperse([], 0)
[]
これは簡単そうです。第一引数のリストに対して、この場合一個ごとにゼロを挿入して、第一引数がひとつか何もない場合はそのまま返しているようです。
雑感
正直この作業は自助努力というかそういう同期で始めたものではないのですが、まだEnumだけで半分以上ある...
もちろんわからないものを図示するのも含めてあとで貴重な教材になるのでしょうが、わからないものをわからないとネットに書くのもなかなかに抵抗があったりします(苦笑
めげずにやるしかないです。
うまずたゆまず、頑張ります。
Kento Mizuno