Elixirのチートシートを作ろう#4 コレクションその２

# 1. Over View

いや、LISTだけでどんどん行数増えてたんで、しかたなく。

# 2. 解説
## 2.1 タプル

さて、Elixir Schoolの引用から。
https://elixirschool.com/ja/lessons/basics/collections#%E3%82%BF%E3%83%97%E3%83%AB-4

タプルはリストに似ていますが、各要素はメモリ上に隣接して格納されます。 このため、タプルの長さを得るのは高速ですが、修正を行うのは高コストとなります。というのも、新しいタプルは全ての要素がメモリにコピーされるからです。タプルは波括弧を用いて定義されます:

```
iex(69)> {3.14, :pie, "Apple"}
{3.14, :pie, "Apple"}
```

なんだ、listの[]が{}で囲まれる様になっただけじゃん…なんて安易な違いじゃない様です。

一文でさらっと解説されてますが、

1) 各要素はメモリ上に隣接して格納されます。 
2) タプルの長さを得るのは高速ですが、修正を行うのは高コストとなります。
   というのも、新しいタプルは全ての要素がメモリにコピーされるからです。

先ほどは気楽にLISTに追加をしてましたが、それが全部「毎回メモリ上に変数をコピーする」ので、
追加とかは困りますね。

これ、LISTの格納のされ方との違いでもあるのですが、複雑な話になるので、別のコラムにします。

さて、使い道。
タプルの長さを得るのは高速なので、関数の引数なんかに使われるそうです。

Elixir Schoolのサンプルが、今後のいろんな勉強の予告編みたいになっちゃいますが、

```
iex(1)> File.read(".condarc")
{:ok, "channels:\r\n  - defaults\r\n"}
iex(2)> File.read(".condarsss")
{:error, :enoent}
```
関数が、:ok, :errorと言うアトムを返しています。
こういう、もう変わらない要素をコレクションするときに使うわけです。
では、これがどう便利に使われるかは…パターンマッチでやりましょう。

## 2.2 キーワードリスト

さぁ、みなさんご一緒に。
（ぴかぴかぴかー）キーワードリスト

連想コレクションですな。そう、僕が大好き連想配列。

さて、Elixir Schoolの引用
```
キーワードリストとマップはElixirの連想コレクションです。
Elixirでは、キーワードリストは最初の要素がアトムのタプルからなる特別なリストで、リストと同様の性能になります。
```
あー、ここでタプル登場。
タプルは要素数が決まってるから、こう言うと時に便利なのね。
これも、関数への引数指定なんかに使われてますな。

```
iex(44)> [foo: "bar", hello: "world"]
[foo: "bar", hello: "world"]
iex(45)> [foo: "bar", hello: "world"]
[foo: "bar", hello: "world"]
iex(46)> [{:foo, "bar"}, {:hello, "world"}]
[foo: "bar", hello: "world"]
iex(47)> [foo: "bar", hello: "world"]
[foo: "bar", hello: "world"]
```
…さて、こんな感じでキーワードリストにアクセスできるのですわ。
atomが、コロンを後ろにつけるfoo:から、取り出すときは:fooと前に着けているのに注意

```
iex(3)> [foo: "bar", hello: "world"][:foo]
"bar"
iex(52)> mokemoke=[foo: "bar", hello: "world"]
[foo: "bar", hello: "world"]
iex(53)> mokemoke[:foo]
"bar"
```

キーワードさえあれば、キーワードリストから要素を簡単に取り出せるので、便利ですね。

## 2.3 マップ

さて、Elixir Schoolの引用
```
Elixirではマップは”花形の”キーバリューストアです。 
キーワードリストとは違ってどんな型のキーも使え、順序付けされません。
マップは %{} 構文で定義することができます:
```

…なんか、こいつ、頭にのってやがりますぜ、花形だってさ。で、その便利さを見てみましょう。
いや、チートシートなんで、お手柔らかに…

```
iex(58)> map = %{:foo => "bar", "hello" => :world}
%{:foo => "bar", "hello" => :world}
iex(59)> map[:foo]
"bar"
iex(60)> map["hello"]
:world
```

最初のkeywordの部分がどんな方でも受け付けるので、とても便利。
さらにっ、変数をマップのキーに出来てますなぁ。

```
iex(65)> key = "hello"
"hello"
iex(66)> %{"hello" => "world"}
%{"hello" => "world"}
iex(67)> %{key => "world"}
%{"hello" => "world"}
```

※実行順を変更しております
ここからが、花形たるゆえんか！？（師範リスペクト）

さて、Elixir Schoolの引用
```
アトムのキーだけを含んだマップには特別な構文があります:
上記の出力からわかるように、アトムのキーだけを含んだマップには特別な構文があります:
```

```
%{:foo => "bar", "hello" => :world}
これを

iex(73)> %{foo: "bar", world: "hello"}
%{foo: "bar", world: "hello"}
iex(74)>

と、書けるんですね。便利。
```

さらに花形な表現が…

```
重複したキーが追加された場合は、前の値が置き換えられます:
```

ちゃんと、警告も出ますなー＝。
```
iex(71)> %{:foo => "bar", :foo => "hello world"}
warning: key :foo will be overridden in map
  iex:71

%{foo: "hello world"}
iex(72)>
```

これは、地味に便利ですね。

いろんな機能はさらに続きます。
```
iex(78)> map = %{foo: "bar", hello: "world"}
%{foo: "bar", hello: "world"}
iex(79)> map.hello
"world"
iex(80)> map.foo
"bar"
```

そして、最後のびっくり

```
マップのもう一つの興味深い特性は、マップの更新のための固有の構文があることです(注: 更新と言っていますが、新しいmapが作成されます):
```

では、見てみましょう。
```
iex(86)> map = %{foo: "bar", hello: "world"}
%{foo: "bar", hello: "world"}
iex(87)> %{map | foo: "baz"}
%{foo: "baz", hello: "world"}
```

Elixir Schoolにも書いてありますが、新しいキーを作成するには、以下の様にput/2を使用します。

```
Map.put(map, :foo, "baz")
%{foo: "baz", hello: "world"}
```

listとは違い、ミニデータベースみたいな感じですね。


# 3. 本日のチートシート
## 3.1 タプル

  |説明|例|
  |:--------------------------------------|:--------|
  |タプルは、{}で括られ、各要素を, 区切ります。|{1, "OverView"}|
  |タプルの長さを得るのは高速ですが、修正を行うのは高コストとなります。<br>というのも、新しいタプルは全ての要素がメモリにコピーされるからです。||


## 3.2 キーワードリスト

  |説明|例|
  |:--------------------------------------|:--------|
  |キーワードリストは、最初の要素がアトムのタプルになります。| [foo: "bar", hello: "world"] |
  |表記が４つあるのに注意してください。<br>[foo: "bar", hello: "world"]<br>[foo: "bar", hello: "world"]<br>[{:foo, "bar"}, {:hello, "world"}]<br>[foo: "bar", hello: "world"]|すべてが上と同じ<br> [foo: "bar", hello: "world"] |
　|atomを指定して、キーワードリストにアクセス|iex(3)> [foo: "bar", hello: "world"][:foo]<br>"bar"<br>atomが、コロンを後ろにつけるfoo:から、取り出すときは:fooと前に着けているのに注意| 
  ||iex(52)> mokemoke=[foo: "bar", hello: "world"]<br>[foo: "bar", hello: "world"]<br>iex(53)> mokemoke[:foo]<br>"bar"

## 3.3 マップ

さて、Elixir Schoolの引用
  |説明|例|
  |:--------------------------------------|:--------|
  |マップは %{} 構文で定義します。<br>マップはキーワードリストと違い、どんな方もキーに出来ます| iex(58)> map = %{:foo => "bar", "hello" => :world} <br> %{:foo => "bar", "hello" => :world}|
  |マップには、キーでアクセスできます|iex(58)> map = %{:foo => "bar", "hello" => :world}<br>%{:foo => "bar", "hello" => :world}<br>iex(59)> map[:foo]<br>"bar"<br>iex(60)> map["hello"]<br>:world<br>|
  |変数をマップのキーに出来ます|iex(65)> key = "hello"<br>"hello"<br>iex(66)> %{"hello" => "world"}<br>%{"hello" => "world"}<br>|
  |アトムのキーだけを含んだマップには特別な構文で書けます|%{:foo => "bar", "hello" => :world}<br>これを<br>iex(73)> %{foo: "bar", world: "hello"}<br>%{foo: "bar", world: "hello"}<br>iex(74)><br><br>と、書ける<br>|
  |重複したキーが追加された場合は、前の値が置き換えられます|iex(71)> %{:foo => "bar", :foo => "hello world"}<br>warning: key :foo will be overridden in map<br>  iex:71<br><br>%{foo: "hello world"}<br>iex(72)><br>|
  |アトムのキーだけを含んだマップには特別な構文で要素にアクセスできます|iex(78)> map = %{foo: "bar", hello: "world"}<br>%{foo: "bar", hello: "world"}<br>iex(79)> map.hello<br>"world"<br>iex(80)> map.foo<br>"bar"|
  |マップの更新のための固有の構文がある|iex(86)> map = %{foo: "bar", hello: "world"}<br>%{foo: "bar", hello: "world"}<br>iex(87)> %{map | foo: "baz"}<br>%{foo: "baz", hello: "world"}<br>|
  |新しいキーを作成するには、put/2を使用します|Map.put(map, :foo, "baz")<br>%{foo: "baz", hello: "world"}<br>|