闘魂Elixir ── 09. Enum.reduce

<b><font color="red">$\huge{元氣ですかーーーーッ！！！}$</font></b>

https://qiita.com/advent-calendar/2022

https://qiita.com/advent-calendar/2022/elixir

# はじめに

闘魂と[Elixir](https://elixir-lang.org/)が出会いました。
闘魂 meets [Elixir](https://elixir-lang.org/).です。
[Elixir](https://elixir-lang.org/) meets 闘魂.でもよいです。

本日は、[Enum.reduce/3](https://hexdocs.pm/elixir/Enum.html#reduce/3)を説明します。

```elixir
iex> "Elixir" |> String.graphemes() |> Enum.frequencies()
%{"E" => 1, "i" => 2, "l" => 1, "r" => 1, "x" => 1}
```

# [Enum.reduce/3](https://hexdocs.pm/elixir/Enum.html#reduce/3)

専門用語で言うと、「畳込み」です。
専門家っぽくなりたいだけなら「reduce、あっ畳込みね」と言っておけばいいです。
専門家になりたければその意味することをしっかりと理解する必要があります。
「関数型の鬼門です」と脅しをいれながら、 **元氣があればなんでもできる！** です。
向上の意気、天を衝くのであります。

Enumerableなものの要素ひとつひとつに関数を適用して、ある形にまとめて行きます。
「Enumerableなもの」がはてな？　の方は、「[闘魂Elixir ── 06. Enumモジュール](https://qiita.com/torifukukaiou/items/bb9d43cde4d667cddb30)」を振り返ってくださいませ。


言葉にするとなんだか難しいかもしれませんが、こちらの図をみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131808/b388fe84-de09-1f62-111a-f04f21bbbfe0.png)




上図の説明をします。[^1]
なかなか複雑ですね。絵が小さいしごちゃごちゃしていますね。ダウンロードして拡大して見てみてください。
`[:cat, :dog, :dog, :dog, :cat, :bird]`がInputです。
結論を先にいうと、リストの中に含まれているアトムの数を数え上げています。
要素1個ずつに関数`f`を適用しています。`acc`の初期値は、空のMap`%{}`です。
関数`f`の実行結果は、次の要素に関数`f`を適用するときの`acc`となります。
[Map.update/4](https://hexdocs.pm/elixir/Map.html#update/4)は、第1引数のMapを更新する関数です。第1引数がMapで、第２引数がキー、第3引数が値です。もしキーがすでにMapに含まれている場合には、第4引数に指定した関数に従って値を更新します。この関数の引数は、現在の値です。`fn cnt -> cnt + 1 end`としておりますので、カウントアップしているわけです。

どうでしょうか、伝わりましたでしょうか。
[Enum.reduce/3](https://hexdocs.pm/elixir/Enum.html#reduce/3)は、[Elixir](https://elixir-lang.org/)を一人前になるときに避けては通れない関数です。


[^1]: 図は、https://excalidraw.com/ を使って作成しています。スゴ腕ハッカーが書いたかのような手書き風の絵が書けるので最近の私のお気に入りツールです。

[IEx](https://hexdocs.pm/iex/IEx.html)で確かめてみましょう。

```:CMD
iex
```

[IEx](https://hexdocs.pm/iex/IEx.html)が立ち上がったら、以下のプログラムを実行してみてください。

```elixir
iex> f = fn v, acc -> Map.update(acc, v, 1, fn cnt -> cnt + 1 end) end

iex> Enum.reduce([:cat, :dog, :dog, :dog, :cat, :bird], %{}, f)
%{bird: 1, cat: 2, dog: 3}
```

`[:cat, :dog, :dog, :dog, :cat, :bird]` => `%{bird: 1, cat: 2, dog: 3}`の変換ができました:tada::tada::tada::tada::tada:


# ワンポイントレッスン

`f`関数は使わなくても以下のように書くことができます。

```elixir
Enum.reduce([:cat, :dog, :dog, :dog, :cat, :bird], %{}, fn v, acc -> Map.update(acc, v, 1, & &1 + 1) end)
```

また、今回の例は[Enum.frequencies/1](https://hexdocs.pm/elixir/Enum.html#frequencies/1)を使うと同じことができます。

```elixir
Enum.frequencies([:cat, :dog, :dog, :dog, :cat, :bird])   
%{bird: 1, cat: 2, dog: 3}
```


# 今日の<font color="#d00080">闘魂</font>

今日は、『孟子』から言葉を引きます。

---
<ruby>浩然之氣<rt>こうぜんのき</rt></ruby>
---

解説は、[こちら](https://imidas.jp/fourchars/detail/X-01-S-10-1-0030.html)をご参照ください。
猪木さん流に言うと、「**すべては、砂漠に遺した足跡。風が吹いたら消え去るだけーー**」ということです。
:book:『[アントニオ猪木自伝](https://presidentstore.jp/item/008105.html)』:book:から引きました。

猪木さんを裏切った相手を躊躇なくリングに上げました。
でっかい心ですべてを包み込みましょう。宇宙から眺めてみましょう。たいていの人間関係はちっぽけなものです。

> わたしは、すべての過去を根に持たないからだ。
> (中略)過去を捨て去る勇気も人生においては大切なのだ。

みなさまもぜひこの本をお手にとられて、猪木さんが残されたメッセージを通じて、直接猪木さんから「元氣」をもらってください。

https://www.shinchosha.co.jp/book/129721/

https://presidentstore.jp/item/008105.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131808/be8933f5-e3e2-d5f4-1561-f65f75abdf38.png)


# さいごに

[Enum.reduce/3](https://hexdocs.pm/elixir/Enum.html#reduce/3)を説明しました。

闘魂の意味は、 **「己に打ち克ち、闘いを通じて己の魂を磨いていくことである」** との猪木さんの言葉をそのまま胸に刻み込んでいます。
知っているだけで終わらせることなく、実行する、断行する、一歩を踏み出すことを自らの行動で示していきたいとおもいます。

<font color="red">$\huge{１、２、３ ぁっダー！}$</font>


<iframe width="910" height="512" src="https://www.youtube.com/embed/AWxwmqzbOaw" title="燃える闘魂 アントニオ猪木  追悼VTR" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

https://www.youtube.com/watch?v=FSz7N5hCltw

---

https://qiita.com/torifukukaiou/items/5e96f4e9f12ec3c4b3f4

---

# Twitter

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Elixir Advent Calendar 3の9日目は、毎度お馴染み <a href="https://twitter.com/torifukukaiou?ref_src=twsrc%5Etfw">@torifukukaiou</a> さんから、今回は関数型の鬼門である「畳込み」関数のElixirバージョン、Enum .reduceです😜<a href="https://t.co/TLcJwLnOJw">https://t.co/TLcJwLnOJw</a><br><br>「畳込み」は、言葉にするとなんだか難しいかも知れませんが、Elixirで一人前になるとき避けては通れない関数😌 <a href="https://t.co/sV39TKe4IU">pic.twitter.com/sV39TKe4IU</a></p>&mdash; piacere (love Elixir, Gravity and VR/AR/Metaverse) (@piacere_ex) <a href="https://twitter.com/piacere_ex/status/1601054315380363264?ref_src=twsrc%5Etfw">December 9, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

---

<b><font color="red">$\huge{元氣があればなんでもできる！}$</font></b>