10
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Elixir: リストに要素を加える

Last updated at Posted at 2019-03-12

リストに要素をひとつ加える場合の書き方です。

リストはヘッドとテイルの組みで表される

リストは|演算子を用いて、頭の要素(ヘッド)と残りのリスト(テイル)に分けることができます。

iex> [head | tail] = [1, 2, 3]
[1, 2, 3]
iex> head
1
iex> tail
[2, 3]

これは、Elixirにおけるリストの内部的な扱いを表しています。つまり、リストはヘッドとテイルの組みを入れ子にしたものです。最後のテイルは空のリスト[]であることにご注目ください。

iex> [1 | [2 | [3 | []]]]
[1, 2, 3]

最後のテイルが空[]でないと、不適切なリストとして扱われます。ただし、特別な環境で使われるため、エラーにはなりません(「List」参照)。

iex> [1 | [2 | [3 | 4]]] 
[1, 2, 3 | 4]

リストのはじめに要素を加える

リスト同士を連結するのは++/2演算子です。要素(item)をリスト(list)のはじめに加える処理は、つぎのように書けます。

[item] ++ list

正しいコードです。けれど、つぎのように内部表現に沿って|演算子を用いる方がよいでしょう。

[item | list]

リストの最後に要素を加える

要素を最後に加えるときは、++/2演算子の出番に思われます。

list ++ [item]

動作に問題はありません。もっとも、最後のリスト要素を見つけなければならないので、サイズが大きいほど効率は落ちます。公式ドキュメントの++/2の解説によれば、はじめに加えて、順序を逆転させる方がよいそうです。

[item |list] |> Enum.reverse()

Erlangによる実装

++/2の実装:erlang.++/2(lists.append/2)を呼び出しています。Erlangの処理はつぎのとおりで、再帰のたびに左辺のリストのコピーがつくられるのです(5「List Handling」5.1「Creating a List」参照)。

append([H|T], Tail) ->
    [H|append(T, Tail)];
append([], Tail) ->
    Tail.

Enum.reverse/1実装が呼び出すErlangの:lists.reverse/1は、反転したリストを新たにひとつつくるだけです。前出5.1「Creating a List」の例を実測した記事「Erlang 入門 (3) - リスト」によると、処理時間に約30倍の開きが出たといいます。

10
5
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
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?