3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ハウインターナショナルAdvent Calendar 2024

Day 15

Elixir Enumモジュールでコードに闘魂を!便利な関数トップ3

Last updated at Posted at 2024-11-05
defmodule FightingSpirit do
  def shout do
    IO.puts "元氣ですかーーーッ!!!"
    IO.puts "元氣があればなんでもできる!"
    IO.puts "闘魂とは己に打ち克つこと。"
    IO.puts "そして闘いを通じて己の魂を磨いていく"
    IO.puts "ことだと思います。"
  end
end

FightingSpirit.shout()

$\huge{元氣ですかーーーッ!!!}$
$\huge{元氣があればなんでもできる!}$

$\huge{闘魂とは己に打ち克つこと。}$
$\huge{そして闘いを通じて己の魂を磨いていく}$
$\huge{ことだと思います。}$

DALL·E 2024-11-02 14.24.45 - .jpeg

はじめに

ElixirEnumモジュールは、リストやマップなどのコレクションを扱う際に非常に便利です。本記事では、日常のプログラムで役立つEnum.map/2, Enum.filter/2, Enum.reduce/3の3つの関数を例を交えながら解説します。それぞれの関数はElixirのコードをシンプルかつ効率的に書くために欠かせない存在です。
独断と偏見ですがよく使います!

1. Enum.map/2でリストの要素を変換する

Enum.map/2はリスト内の各要素を順番に処理し、新しいリストを生成する関数です。使い方は、変換したいリストと処理を行う無名関数を渡すだけです。

例: 値を2倍にする

以下のコードはリスト内の値を2倍に変換します。

list = [1, 2, 3, 4]
new_list = Enum.map(list, fn x -> x * 2 end)

実行結果

実行結果は次のようになります。

[2, 4, 6, 8]

解説

Enum.map/2は、リストの要素ごとに無名関数fn x -> x * 2 endを適用し、新しいリストを返しています。このように簡潔に変換処理を行えるため、データの加工に便利です。

ちなみに無名関数は& &1 * 2とも書けます。この書き方もよく見かけるので覚えておくとよいでしょう。


2. Enum.filter/2で条件に合う要素を選択する

Enum.filter/2は、リストの要素の中から指定した条件に合う要素だけを抽出する関数です。リストとフィルターを行う無名関数を渡すと、新しいリストが返ってきます。

例: 偶数だけを抽出する

以下のコードは、リストの中から偶数のみを抽出します。

list = [1, 2, 3, 4, 5, 6]
even_list = Enum.filter(list, fn x -> rem(x, 2) == 0 end)

実行結果

実行結果は次のようになります。

[2, 4, 6]

解説

Enum.filter/2は、各要素を無名関数fn x -> rem(x, 2) == 0 endで偶数かどうかを確認し、条件を満たす(つまり偶数である)要素だけをリストに残しています。条件に合うデータだけを取り出したいときに非常に便利です。


3. Enum.reduce/3でリストを畳み込む

Enum.reduce/3はElixirの最初の鬼門です。専門家の間では畳み込みと呼ばれます。
Enum.reduce/3は、リストの全ての要素を他の表現へ畳み込む関数です。これまでみてきたEnum.map/2Enum.filter/2はリストが得られていました。それに対してEnum.reduce/3は、初期値と処理を行う関数を渡すことで、他の型のデータを作ることができます。

例: リスト内の要素の出現回数を数える

以下のコードでは、リスト内の要素(アトム)の出現回数を数えてマップを返しています。

list = [:inoki, :baba, :inoki, :baba, :inoki]
Enum.reduce(list, %{}, fn e, acc -> Map.update(acc, e, 1, & &1 + 1) end)

実行結果

実行結果は次のようになります。

%{inoki: 3, baba: 2}

解説

ここでは、Enum.reduce/3に初期値として空のマップ%{}と無名関数fn e, acc -> Map.update(acc, e, 1, & &1 + 1)を渡し、リスト内の要素を次々と数えています。
無名関数の第1引数eはリストの要素です。第2引数のaccはアキュムレータと呼ばれるもので直前までの無名関数の評価結果です。最初は初期値の空のマップ%{}が入っています。具体的には以下のように更新されていきます。

Index e acc 評価結果
0 :inoki %{} %{inoki: 1}
1 :baba %{inoki: 1} %{inoki: 1, baba: 1}
2 :inoki %{inoki: 1, baba: 1} %{inoki: 2, baba: 1}
3 :baba %{inoki: 2, baba: 1} %{inoki: 2, baba: 2}
4 :inoki %{inoki: 2, baba: 2} %{inoki: 3, baba: 2}

Enum.reduce/3は、集約処理や合計計算などに役立つ関数です。

ちなみにこの例と同じことは、Enum.frequencies/1一発でできることを付記しておきます。


どうやって実行するんだー!? バカヤローって方へ

GitHubのアカウントをお持ちの方へお手軽な方法を示しておきます。
PhoenixアプリケーションをGitHub Codespaces上で開発する方法で紹介したGitHub Codespacesを使うという方法です。

記事中で紹介しているphx_devcontainerを使うと、ElixirがインストールされたUbuntuコンテナが立ち上がるので、Ubuntu上で直接開発をしているかのように操作ができます。iexコマンドでREPL(Read-Eval-Print Loop)が立ち上がるのでこの記事のコード例をぜひ試してください。

スクリーンショット 2024-11-02 14.11.07.png


まとめ

ElixirのEnumモジュールには、データ操作をシンプルにしてくれる便利な関数が揃っています。今回紹介したEnum.map/2, Enum.filter/2, Enum.reduce/3は特に日常的によく使うデータ処理や変換に不可欠な存在です。

一手一手に闘魂を込めて、シンプルで力強いコードを書いていきましょう!

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?