Help us understand the problem. What is going on with this article?

Elixir~Enum総ざらい4回目~

More than 1 year has passed since last update.

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

kmizuno0211
音楽家。 #みずの音楽教室 という屋号で各種音楽制作やってます。宙に浮いた扁平足ギターボーカル。
https://note.mu/kmizuno0211
fukuokaex
エンジニア/企業向けにElixirプロダクト開発・SI案件開発を支援する福岡のコミュニティ
https://fukuokaex.fun/
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