Elixir - Maps



关键字列表是一种通过键访问存储在列表中的内容的便捷方法,但在底层,Elixir 仍然需要遍历整个列表。如果您对该列表还有其他需要遍历所有元素的计划,这可能是合适的,但如果您计划仅使用键作为访问数据的方式,则这可能是不必要的开销。

这就是 maps 能够帮助您的地方。无论何时您需要键值存储,maps 都是 Elixir 中的“首选”数据结构。

创建 Map

使用 %{} 语法创建 map:

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

与关键字列表相比,我们已经可以看到两个区别:

  • Maps 允许任何值作为键。
  • Maps 的键不遵循任何顺序。

访问键

为了访问与键关联的值,Maps 使用与关键字列表相同的语法:

map = %{:a => 1, 2 => :b}
IO.puts(map[:a])
IO.puts(map[2])

运行以上程序时,会生成以下结果:

1
b

插入键

要在 map 中插入键,我们使用 Dict.put_new 函数,该函数以 map、新键和新值作为参数:

map = %{:a => 1, 2 => :b}
new_map = Dict.put_new(map, :new_val, "value") 
IO.puts(new_map[:new_val])

这将在新的 map 中插入键值对 :new_val - "value"。运行以上程序时,会生成以下结果:

"value"

更新值

要更新 map 中已存在的值,可以使用以下语法:

map = %{:a => 1, 2 => :b}
new_map = %{ map | a: 25}
IO.puts(new_map[:a])

运行以上程序时,会生成以下结果:

25

模式匹配

与关键字列表相比,maps 在模式匹配中非常有用。当 map 用于模式时,它将始终匹配给定值的子集:

%{:a => a} = %{:a => 1, 2 => :b}
IO.puts(a)

以上程序生成以下结果:

1

这将使 a1 匹配。因此,它将生成输出 1

如上所示,只要模式中的键存在于给定的 map 中,map 就会匹配。因此,空 map 匹配所有 map。

在访问、匹配和添加 map 键时可以使用变量:

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

Map 模块 提供了与 Keyword 模块非常相似的 API,以及用于操作 map 的便捷函数。您可以使用诸如 Map.get, Map.delete 之类的函数来操作 map。

带有原子键的 Maps

Maps 有一些有趣的特性。当 map 中的所有键都是原子时,您可以使用关键字语法以获得便利:

map = %{:a => 1, 2 => :b} 
IO.puts(map.a) 

maps 的另一个有趣的特性是它们提供了自己的语法来更新和访问原子键:

map = %{:a => 1, 2 => :b}
IO.puts(map.a)

以上程序生成以下结果:

1

请注意,要以这种方式访问原子键,它必须存在,否则程序将无法工作。

广告