Elixir チュートリアル キーワードリストとMap

Elixir チュートリアルやらないで触ってたのでおさらいがてらめもめも

キーワードリスト

  • key_map 的な奴
iex> list = [{:a, 1}, {:b, 2}]
[a: 1, b: 2]
iex> list == [a: 1, b: 2]
true
iex> list[:a]
1
  • 追加するときは ++
iex> [a: 0] ++ list
[a: 0, a: 1, b: 2]

キーワードリストは2つの特別な特徴があるため重要です:

  • キーの順序を開発者が指定したとおりに保持する
  • キーを複数回与えることができる

Ecto なんかはこの2つの機能を使っている

query = from w in Weather,
      where: w.prcp > 0,
      where: w.temp < 20,
     select: w

where という key を二回与えていて、where の順番を守っている

iex> if false, do: :this, else: :that
:that

↓ コレと一緒

iex> if(false, [do: :this, else: :that])
:that

注意点

  • リストと同じ線形の性能特性をもっている

    • 素数が多いと捜査するのに時間がかかる
    • -> 要素数が多くなり過ぎないオプションなどに適してる
    • -> Map を使うようにする
  • パターンマッチできるけど順番とアイテム数もマッチしなくちゃダメだから使いみちはそんなにない

iex> [a: a] = [a: 1]
[a: 1]
iex> a
1
iex> [a: a] = [a: 1, b: 2]
** (MatchError) no match of right hand side value: [a: 1, b: 2]
iex> [b: b, a: a] = [a: 1, b: 2]
** (MatchError) no match of right hand side value: [a: 1, b: 2]

Map

キーワードリストより早い。使い方は %{} これ

  • キーワードリストと違う点
    • 順不同
    • キーの型はなんでも良い
iex> map = %{:a => 1, 2 => :b}
%{2 => :b, :a => 1}
iex> map[:a]
1
iex> map[2]
:b

同じキーを渡した場合は,最後の奴が出てくる

iex> %{1 => 1, 1 => 2}
%{1 => 2}

全部のキーが atom の場合はキーワード構文が使える

  • 順不同で良いならキーワードリスト使わずにこっちって感じ
iex> map = %{a: 1, b: 2}
%{a: 1, b: 2}

順不同でアイテム数も関係なくパターンマッチできるので Map のパターンマッチは使いやすい

iex> %{} = %{:a => 1, 2 => :b}
%{:a => 1, 2 => :b}
iex> %{:a => a} = %{:a => 1, 2 => :b}
%{:a => 1, 2 => :b}
iex> a
1
iex> %{:c => c} = %{:a => 1, 2 => :b}
** (MatchError) no match of right hand side value: %{2 => :b, :a => 1}

その他の特殊な構文

iex> map = %{:a => 1, 2 => :b}
%{:a => 1, 2 => :b}
iex> map.a
1
iex> %{map | :a => 2}
%{:a => 2, 2 => :b}
iex> %{map | :c => 3}
** (ArgumentError) argument error

はい便利ですね

Dict なくなるらしいので割愛

qiita.com

気になるならこっちをみてちょんまげ