LoginSignup
15
2

More than 1 year has passed since last update.

未経験文系初学者 Elixirを学ぶ 『プログラミングElixir』-第7章

Last updated at Posted at 2022-05-05

こんにちは!
プログラミング未経験文系出身、Elixirの国に迷い込んだ?!見習いアルケミストのaliceと申します。
今回はElixirの教科書『プログラミングElixir』第7章を読んで、学んだことをまとめます。1

目次

第4章へはこちらから
第5章へはこちらから
第6章へはこちらから

実行環境

・Windows 11 Home(バージョン 21H2, OS ビルド 22000.613)
・Ubuntu v18.04 ※WSL2環境下
・Elixir v1.13.0 (compiled with Erlang/OTP 24) ※WSL2環境下
・Phoenix v1.6.7 ※WSL2環境下
・psql (PostgreSQL) 10.19 ※WSL2環境下

以下私が詰まった箇所です。それ以外は本書か
Elixir公式の学習ページか、Elixir Schoolかで、学ぶことができます。

7.1 ヘッドとテイル & 7.2 ヘッドとテイルによるリストの処理

リストはヘッドとそれ以外のテイル。テイルはリスト。再帰的になっている。

※変数の頭に_(アンダースコア)を入れると、その変数がモジュール内で一度も使用されていない場合の警告が出なくなる。

7.3 ヘッドとテイルを使ったリストの構築

,(カンマ)と|(パイプ)記号1つ違うと意味が全く変わるので注意。

# do: の後ろが , になっている場合
def add_1([]), do: []
def add_1([head | tail]),  do: [head+1 , add_1(tail)]


#例
def add_1([2, 4, 12])
   -> [2+1, add_1([4,12])]
     -> [3, [4+1, add_1([12])]]
       -> [3, [5, [12+1, add_1[]]]]
         -> [3, [5, [13, []]]]  #多重リスト(入れ子)になる
# do: の後ろが | になっている場合
def add_1([]), do: []
def add_1([head | tail]),  do: [head+1 | add_1(tail)]

#例
=def add_1([2, 4, 12])
   -> [2+1 | add_1([4, 12])
     -> [3 | [4+1 | add_1([12])]
       -> [3 | [5 | [12+1 | add_1[])]]
         -> [3 | [5 | [13 | []]]]
           -> [3] ++ [5] ++ [13] ++ [] # | はパターンマッチ以外においては ++ (リストの連結)の意味
             ->[3, 5, 13] #連結リストになる 

7.4 map関数の作成

map/2 関数(enumerable, fun)
リストと関数を引数とし、それぞれの要素に関数を適用して、新しいリストを返す。

iex()> Enum.map([1, 2, 3, 4], fn(n) -> n + 1 end)
[2, 3, 4, 5]

iex()> Enum.map([1, 2, 3, 4], fn(n) -> n > 2 end)
[false, false, true, true]

iex()> Enum.map([1, 2, 3, 4], fn(n) -> n + 1 > 2 end)
[false, true, true, true]

iex()> Enum.map([1, 2, 3, 4], fn(n) -> n + 1 >= 2 end)
[true, true, true, true]

#略記するとこんな感じ↓ かっこやendタグの有無は慣れよう。
iex()> Enum.map [1,2,3,4], &(&1+1)
[2, 3, 4, 5]

iex()> Enum.map [1,2,3,4], &(&1) > 2
[false, false, true, true]

iex()> Enum.map [1,2,3,4], &(&1+1) > 2
[false, true, true, true]

iex()> Enum.map [1,2,3,4], &(&1+1) >= 2
[true, true, true, true]

7.5 リストを単一の値にまとめる

reduce/3 関数(enumerable, acc, fun)
初期値(acc)とリスト(enumerable)のヘッドの値に対して関数(fun)を実行し、実行結果を次の初期値とし、リストの次の値を取り出して、同様に関数を実行する。これをリストの末尾に到達するまで再帰的に繰り返す。

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

7.6 より複雑なリストのパターン

リストのヘッド部は複数の条件を組みあわせることができる。

  @doc """
  paramater swap.

  ## Examples
      iex> Practice.swap([])
      []
      iex> Practice.swap([2, 4, 6, 8])
      [4, 2, 8, 6]
  """

def swap([]), do: []
#空のリストが渡された時はそれをそのまま出力する。

def swap([a, b | tail]), do: ([b, a | swap(tail)])
#要素がa, b のペア、つまり、要素数が偶数個のリストが渡された時はそれをそのまま出力する。

def swap(_), do: raise "Can't swap a list with an odd number of elements" 
#それ以外、つまり、要素数が奇数個のリストが渡されたときは続くエラーメッセージを出力する。
#  ** (RuntimeError) Can't swap a list with an odd number of elementsというエラーメッセージが返ってくるのが期待値

7.7 実践Listモジュール & 7.8 リストと仲良くなろう

Elixirに標準組み込み済みのListモジュール。公式ドキュメントはこちらから

flatten/1 (list)関数

平滑化 = 多重リストの入れ子をなくす。

iex()> List.flatten([100, [200, 300, [400, 500], [600]]])
[100, 200, 300, 400, 500, 600]

replace_at/3 (list, index, value) 関数

リスト内のindexが条件と一致する場所にある要素を置き換える。
indexは0から始まる(つまり、要素の2番目はインデックス的には1)

iex()> list = [1, 2, 3]
[1, 2, 3]

iex()> List.replace_at(list, 2, "buckle my shoe")
[1, 2, "buckle my shoe"]

keyfind/3 (list, key, position, default \ nil)関数

positionにおけるkeyが条件が最初に一致したタプルを返す。
positionはタプル内におけるindexみたいなものか?

iex()> kw = [{:name, "Dave"}, {:likes, "Programming"}, {:where, "Dallas", "TX"}]
[{:name, "Dave"}, {:likes, "Programming"}, {:where, "Dallas", "TX"}]

iex()> List.keyfind(kw, :likes, 0)
{:likes, "Programming"}

iex()> List.keyfind(kw, "Dallas", 1)
{:where, "Dallas", "TX"}

iex()> List.keyfind(kw, "TX", 2)
{:where, "Dallas", "TX"}

iex()> List.keyfind(kw, "Dallas", 2) #position2に存在するkeyが条件と一致しない
nil


~Elixirの国のご案内~

※Elixirって何ぞや?と思ったらこちらもどぞ。未来がぎゅっと詰まった、Elixirは今年で生まれて10周年です:laughing::sparkles::sparkles:

We Are The Alchemists, my friends!:bouquet:2
Elixirコミュニティは本当に優しくて温かい人たちばかり!
私が挫折せずにいられるのもこの恵まれた環境のおかげです。

まずは気軽に話しかけてみてください。3

  1. プログラミングが完全未経験ゆえ、「え?!そこからつまずく?!!」というお見苦しい箇所があるかと思いますが、私自身の記録のために残します。ご了承ください。

  2. @torifukukaiouさんのAwesomeな名言をお借りしました。Elixirコミュニティを一言で表すと、これに尽きます。

  3. @kn339264さんの素敵なスライドをお借りしました。Elixirコミュニティはいろんな形で活動中!

15
2
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
15
2