Elixir 映射

2023-12-14 17:01 更新

当你需要存储键值对的时候,映射就是Elixir中最合适的数据结构。使用%{}语法创建一个映射:

iex> map = %{:a => 1, 2 => :b}
%{2 => :b, :a => 1}
iex> map[:a]
1
iex> map[2]
:b
iex> map[:c]
nil

与关键词列表相比较,我们能发现两个不同点:

- 映射允许使用任何值作为键
- 映射的键是无序的

与关键词列表相反,映射非常适合模式匹配。只需要左边是右边的子集就能够匹配:

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

如上所示,一个映射只需要它的键在给定的映射中存在就能匹配。因此,空映射匹配任何映射。

在访问,匹配,添加映射键时可以使用变量:

iex> n = 1
1
iex> map = %{n => :one}
%{1 => :one}
iex> map[n]
:one
iex> %{^n => :one} = %{1 => :one, 2 => :two, 3 => :three}
%{1 => :one, 2 => :two, 3 => :three}

Map模块提供了一个与Keyword非常相似的API,包含了一系列方便操作映射的函数:

iex> Map.get(%{:a => 1, 2 => :b}, :a)
1
iex> Map.to_list(%{:a => 1, 2 => :b})
[{2, :b}, {:a, 1}]

当映射中所有键都是原子时,你可以简写成关键词形式:

iex> map = %{a: 1, b: 2}
%{a: 1, b: 2}

另一个有趣的特性是,映射有着独特的语法用于访问和更新原子键:

iex> map = %{:a => 1, 2 => :b}
%{2 => :b, :a => 1}

iex> map.a
1
iex> map.c
** (KeyError) key :c not found in: %{2 => :b, :a => 1}

iex> %{map | :a => 2}
%{2 => :b, :a => 2}
iex> %{map | :c => 3}
** (KeyError) key :c not found in: %{2 => :b, :a => 1}

访问和更新都要求所提供的键存在。例如,因为映射中不存在:c键,所以访问和更新:c键失败了。

Elixir开发者通常偏好使用map.field格式以及模式匹配,而非Map模块中的函数,因为前者具有一种目的明确的编程风格。这篇文章提供了观点和例子,关于如何在Elixir中通过编写目的明确的代码来获得更简洁快速的软件。

最近映射已经被引入了Erlang虚拟机中,而且从Elixir v1.2版本起它们开始能够有效地支持数以百万的键。因此,如果你在使用之前的Elixir版本(V1.0或v1.1),并且想要支持至少几百个键,那么你也许该考虑HashDict模块。

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号