Elixir Schoolの学習メモです。
リスト
リストは事実上連結データ構造。
リストの長さを取得するのは線形時間(O(n))の処理になるので(要素数が多いほど時間がかかる)ので、先頭へ追加するほうが高速
# リスト先頭への追加(高速)
iex> ["π" | list]
["π", 3.14, :pie, "Apple"]
# リスト末尾への追加(低速)
list ++ ["Cherry"]
iex> [3.14, :pie, "Apple", "Cherry"]
++/2演算子
++/2演算子はリストの連結に用いられます。
名前付き関数は、名前とパラメータの数(アリティ、arity)の2つで成ります。
アリティはElixir、Erlangのコードを説明するときの中核となるものです。大事!
リストの減算には strict comparison(===)が使われます。
iex> [2] -- [2.0]
[2]
iex> [2.0] -- [2.0]
[]
リストの頭部、尾部(ヘッド、テイル)
リストを扱う際には、よくリストのヘッドとテイルを利用する。
ヘッドはそのリストの最初の要素で、テイルは残りの要素。
Elixirではこれらを扱うためにhd
とtl
という関数がある。
iex(29)> hd [3.14, :pie, "Apple"]
3.14
iex(30)> tl [3.14, :pie, "Apple"]
[:pie, "Apple"]
パターンマッチングやcons演算子(|
)を使うこともできる。
iex(32)> [head | tail] = [3.14, :pie, "Apple"]
[3.14, :pie, "Apple"]
iex(33)> head
3.14
iex(34)> tail
[:pie, "Apple"]
タプル
タプルは順序を持ったコレクション。他のすべてのElixirの構造体と同じく、一度作られたタプルは変更できない。
{1, 2} {:ok, 42, "next"} {:error, :enoent}
キーワードリスト
キーワードリストはマップとともに連想コレクション。
[foo: "bar", hello: "world"]
Elixirは2つの要素を持つタプルのリストに変換する。
[{foo: "bar"}, {hello: "world"}]
キーワードリストの特徴
- キーはアトム
- キーは順序付けされている
- キーの一意性は保証されない
キーワードリストは関数にオプションを渡すためによく用いられる。
マップ
マップはキーと値のペアのコレクション。
%{ key => value, key => value }
アトムがキーの場合はショートカットが使える。
%{ red: 0xff0000, green: 0x00ff00 }
マップのキーが重複している場合、前の値が置き換えられる。
iex> %{:foo => "bar", :foo => "hello world"}
%{foo: "hello world"}
アトムのキーにアクセスするための構文。
iex(20)> map = %{foo: "bar", hello: "world"}
%{foo: "bar", hello: "world"}
iex(21)> map.hello
"world"
マップの存在するキーを更新する。
存在しないキーはKeyError
が発生。
iex(23)> map = %{foo: "bar", hello: "world"}
%{foo: "bar", hello: "world"}
iex(24)> %{map | foo: "baz"}
%{foo: "baz", hello: "world"}
iex(25)> %{map | wry: "baz"}
** (KeyError) key :wry not found in: %{foo: "bar", hello: "world"}
(stdlib 4.0) :maps.update(:wry, "baz", %{foo: "bar", hello: "world"})
(stdlib 4.0) erl_eval.erl:309: anonymous fn/2 in :erl_eval.expr/6
(stdlib 4.0) lists.erl:1350: :lists.foldl/3
新しいキーを作成するにはMap.put/3
を使う。
iex(26)> Map.put(map, :wry, "baz")
%{foo: "bar", hello: "world", wry: "baz"}