/var/log/messages

Apr 11, 2019 - 2 minute read - Comments - programming

Enum、Map、String などの確認

昨日エントリ関連でよく分からない手続きについて確認した事項を以下に列挙します。

Enum.join

テキストだと以下な使い方でした。

defp get_all_graphemes(texts) do
  texts
  |> Enum.join()
  |> String.graphemes()
end

以下な使用例が例示されていて

iex> Frequency.frequency(["Freude", "schöner", "Götterfunken"], workers)

Example によれば

iex> Enum.join([1, 2, 3])
"123"

とのこと。成程。ちなみに以下な書き方は default 引数みたいですね。

join(enumerable, joiner \\ "")

Enum.reduce

テキストでは以下な使い方です。

defp count_letters(graphemes) do
  Enum.reduce(graphemes, %{}, fn grapheme, acc ->
    if String.match?(grapheme, ~r/^\p{L}$/u) do
      downcased_letter = String.downcase(grapheme)
      Map.update(acc, downcased_letter, 1, fn count -> count + 1 end)
    else
      acc
    end
  end)
end

reduce/3 になるのか。

加算な例が例示されています。

iex> Enum.reduce([1, 2, 3], 0, fn x, acc -> x + acc end)
6

む、String.graphemes って何だろう。

String.graphemes

なるほど、配列要素の中に文字列がはいってるソレを一つの文字列として join してそこから String の配列を生成しているのか。

以下なナニが例示。

iex> String.graphemes("Ńaïve")
["Ń", "a", "ï", "v", "e"]

Map.update

update/4 ですね。

ええと、以下な定義になっていて

update(map(), key(), value(), (value() -> value())) :: map()

map にある key を与えられた手続きで update、なのか。mapkey な要素があれば値を更新、なければ value な初期値で設定、なのか成程。これで count_letter の実装に得心しました。

String.match? の部分

おそらくは印字可能な文字、という事のはずなのですがどうなのか。以下によれば

Unicode 文字列かどうかを判定している模様。成程。

Enum.chunk_every

chunk_every/2chunk_every(enumerable, count, count) への shortcut とのことで以下を確認。

定義としては以下、とのこと。

chunk_every(enumerable, count, step, leftover \\ []) 
chunk_every(t(), pos_integer(), pos_integer(), t() | :discard) :: [list()]

以下が例示されている。

Enum.chunk_every([1, 2, 3, 4, 5, 6], 2)
[[1, 2], [3, 4], [5, 6]]

上記だと

Enum.chunk_every([1, 2, 3, 4, 5, 6], 2, 2, [])

が呼び出されるのか。countstep なのか。成程、これを使って chunk を生成、なのか。

Map.merge

以下な形で使っています。

defp merge_results_stream(results_stream) do
  Enum.reduce(results_stream, %{}, fn {:ok, worker_result}, acc ->
    Map.merge(acc, worker_result, fn _key, acc_val, worker_val ->
      acc_val + worker_val
    end)
  end)
end

merge/3 は以下。

results_stream は配列の stream なのでその要素の :ok なナニと accumulater を手続きに渡している形ですね。その中では

  • acc と worker_result (両方 map のはず) を加算、なのか

ドキュメントでも以下な記述があります。map は足し算できるのですね。

iex> Map.merge(%{a: 1, b: 2}, %{a: 3, d: 4}, fn _k, v1, v2 ->
...>   v1 + v2
...> end)
%{a: 4, b: 2, d: 4}

Concurrency and Parallelism in Elixir re:Work

comments powered by Disqus