Elixirモジュールまとめ（Map編）

# 概要
- Dict、Map、Keywordはほとんど同じ関数を持つモジュールで、扱えるデータ型が異なる

|Dict|Map|Keyword|
|---|---|---|
|マップ、キーワードリスト|マップ|キーワードリスト|
  
- ドキュメントでは引数に`dict`と`map`が両方使われているが、MapとKeywordについてはそれぞれ対応する型のみ

以降は[Mapモジュール](http://elixir-lang.org/docs/stable/elixir/Map.html)のまとめ

# delete(map, key)
- キーを含むマップをmapから削除する
- なければmapをそのまま返す

```ex
m = %{a: 1, b: 2}

Map.delete(m, :a)
# %{b: 2}

Map.delete(m, :hoge)
# %{a: 1, b: 2}
```

# drop(dict, keys)
- keys（リスト）を含むマップをdictから削除する
- なければdictをそのまま返す

```ex
m = %{a: 1, b: 2, c: 3}
k = [:a, :b]

Map.drop(m, k)
# %{c: 3}

Map.drop(m, [:hoge])
# %{a: 1, b: 2, c: 3}
```

# equal?(dict1, dict2)
- dict1とdict2が同一のマップか判定する

```ex
m = %{a: 1, b: 2}
m2 = %{a: 1, b: 2}

Map.equal?(m, m2)
# true
```

# fetch!(dict, key)
- dictからkeyに対応する値を返す

```ex
m = {a: 1, b: 2, c: 3}

Map.fetch!(m, :a)
# 1

Map.fetch!(m, :hoge)
# KeyError
```

# fetch(map, key)
- mapからkeyに対応する値を`{:ok, value}`で返す
- なければ`:error`

```ex
m = {a: 1, b: 2, c: 3}

Map.fetch!(m, :a)
# {:ok, 1}

Map.fetch!(m, :hoge)
# :error
```

# from_struct(struct)
- 構造体をマップに変換する

```ex
defmodule Hoge do
  defstruct name: hoge, age: 100
end

%Hoge{}
# %Hoge{age: 100, name: "hoge"}

Map.from_struct(%Hoge{})
# %{age: 100, name: "hoge"}
```

# get(dict, key, default \\ nil)
- dictからkeyに対応する値を返す
- keyが存在しない場合、defaultを返す
- keyが存在しない、かつdefaultを指定しない場合、nilを返す

```ex
m = {a: 1, b: 2, c: 3}

Map.get(m, :a)
# 1

Map.get(m, :a, "default")
# 1

Map.get(m, :hoge, "default")
# default

Map.get(m, :hoge)
# nil
```

# has_key?(dict, key)
- dictにkeyが存在するか判定する

```ex
m = {a: 1, b: 2, c: 3}

Map.has_key?(m, :a)
# true

Map.has_key?(m, :home)
# false
```

# keys(dict)
- dictが持つ全てのキーをリストで返す

```ex
m = {a: 1, b: 2, c: 3}

Map.keys(m)
# [:a, :b, :c]
```

# merge(map1, map2)
- map1とmap2をマージする
- 同じキーが存在する場合、map2に指定した値を採用する

```ex
m = %{a: 1, b: 2}
m2 = %{c: 3, d: 4}

Map.merge(m, m2}
# %{a: 1, b: 2, c: 3, d: 4}

m3 = %{a: 11, b: 22}

Map.merge(m, m3)
# %{a: 11, b: 22}

Map.merge(m3, m)
# %{a: 1, b: 2}
```

# merge(dict1, dict2, fun \\\ fn _k, _v1, v2 -> v2 end)
- 同一キーのキーと値に対するコールバック関数を第三引数に指定する

```ex
m = %{a: 1, b: 2}
m2 = %{a: 11, b: 22}

Map.merge(m, m2, fn k, v1, v2 -> v1 end)
# %{a: 1, b: 2}

Map.merge(m, m2, fn k, v1, v2 -> v2 end)
# %{a: 11, b: 22}

m3 = {c: 3, d: 4}

Map.merge(m, m3, fn k, v1, v2 -> v2 end)
# %{a: 1, b: 2, c: 3, d: 4}
```

# new()
- 空のマップを返す

```ex
Map.new()
# %{}
```

# pop(dict, key, default \\\ nil)
- dictからkeyに対応する値と、それ以外のマップを返す
- keyが存在しなければdefaultを返す
- keyが存在しない、かつdefaultを指定しない場合、nilを返す

```ex
m = %{a: 1, b: 2, c: 3}

Map.pop(m, :a)
# {1, %{b: 2, c: 3}}

{v, mm} = Map.pop(m, :a)
v
# 1
mm
# %{b: 2, c: 3}

Map.pop(m, :hoge)
# {nill, %{a: 1, b: 2, c: 3}}

Map.pop(m, :hoge, "fuga")
# {"fuga", %{a: 1, b: 2, c: 3}}
```

# put(map, key, val)
- mapの末尾に`key:val`を追加したマップを返す
- keyが既に存在している場合、valに上書きする。

```ex
m = %{a: 1, b: 2}

Map.put(m, :c, 3)
# %{a: 1, b: 2, c: 3}

Map.put(m, :b "hoge")
# %{a: 1, b: "hoge"}
```

# put_new(dict, key, val)
- mapの末尾に`key:val`を追加したマップを返す
- keyが既に存在していたら、dictをそのまま返す

```ex
m = %{a: 1, b: 2}

Map.put(m, :c, 3)
# %{a: 1, b: 2, c: 3}

Map.put(m, :b "hoge")
# %{a: 1, b: 2}
```

# size(map)
- mapのサイズを返す

```ex
m = %{a: 1, b: 2}

Map.size(m)
# 2

Map.size(%{})
# 0
```

# split(dict, keys)
- dictを、keysに対応するマップとそれ以外の2つのマップに分割して返す

```ex
m = %{a: 1, b: 2, c: 3, d: 4, e: 5}

Map.split(m, [:b, :d])
# {%{b: 2, d: 4}, %{a: 1, c: 3, e: 5}}

Map.split(m, [])
# {%{}, %{a: 1, b: 2, c: 3, d: 4, e: 5}}
```

# take(dict, keys)
- dictからkeysに対応するマップだけを返す

```ex
m = %{a: 1, b: 2, c: 3, d: 4, e: 5}

Map.split(m, [:b, :d])
# %{b: 2, d: 4}

Map.split(m, [])
# %{}
```

# to_list(dict)
- dictをキーワードリストに変換する

```ex
m = %{a: 1, b: 2, c: 3}

Map.to_list(m)
# [a: 1, b: 2, c: 3]

Map.to_list(%{})
# []
```

# update!(dict, key, fun)
- dictからkeyに対応する値を抽出し、その値にfunを実行したマップを返す
- dictに存在しないkeyを指定するとエラー

```ex
m = %{a: 1, b: 2, c: 3}

Map.update!(m, :b, fn v -> v * 2 end)
# %{a: 1, b: 4, c: 3}

Map.update!(m, :hoge, fn v -> v * 2 end)
# KeyError
```

# update(dict, key, initial, fun)
- dictからkeyに対応する値を抽出し、その値にfunを実行したマップを返す
- dictに存在しないkeyを指定すると、`key: initial`が末尾に追加されたマップを返す
- initialに対してfunは実行されない

```ex
m = %{a: 1, b: 2, c: 3}

Map.update(m, :b, "fuga", fn v -> v * 2 end)
# %{a: 1, b: 4, c: 3}

Map.update(m, :hoge, "fuga", fn v -> v * 2 end)
# %{a: 1, b: 4, c: 3, hoge: "fuga"}
```

# values(dict)
- dictが持つ全ての値をリストで返す

```ex
m = %{a: 1, b: 2, c: 3}

Map.values(m)
# [1, 2, 3]
```