10
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Last updated at Posted at 2024-12-06

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"}
タプルの長さを得るのは高速ですが、修正を行うのは高コストとなります。
というのも、新しいタプルは全ての要素がメモリにコピーされるからです。

3.2 キーワードリスト

説明
キーワードリストは、最初の要素がアトムのタプルになります。 [foo: "bar", hello: "world"]
表記が4つあるのに注意してください。
[foo: "bar", hello: "world"]
[foo: "bar", hello: "world"]
[{:foo, "bar"}, {:hello, "world"}]
[foo: "bar", hello: "world"]
すべてが上と同じ
[foo: "bar", hello: "world"]
  atomを指定して、キーワードリストにアクセス
iex(52)> mokemoke=[foo: "bar", hello: "world"]
[foo: "bar", hello: "world"]
iex(53)> mokemoke[:foo]
"bar"

3.3 マップ

さて、Elixir Schoolの引用

説明
マップは %{} 構文で定義します。
マップはキーワードリストと違い、どんな方もキーに出来ます
iex(58)> map = %{:foo => "bar", "hello" => :world}
%{:foo => "bar", "hello" => :world}
マップには、キーでアクセスできます iex(58)> map = %{:foo => "bar", "hello" => :world}
%{:foo => "bar", "hello" => :world}
iex(59)> map[:foo]
"bar"
iex(60)> map["hello"]
:world
変数をマップのキーに出来ます iex(65)> key = "hello"
"hello"
iex(66)> %{"hello" => "world"}
%{"hello" => "world"}
アトムのキーだけを含んだマップには特別な構文で書けます %{: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"
マップの更新のための固有の構文がある iex(86)> map = %{foo: "bar", hello: "world"}
%{foo: "bar", hello: "world"}
iex(87)> %{map
新しいキーを作成するには、put/2を使用します Map.put(map, :foo, "baz")
%{foo: "baz", hello: "world"}
10
1
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
10
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?