非常教程

Elixir 1.5参考手册

地图 | Map

地图 | Map

一组用于处理地图的函数。

地图是Elixir中的“前往”键值数据结构。地图可以用%{}语法创建,键值对可以表示为key => value

iex> %{}
%{}
iex> %{"one" => :two, 3 => "four"}
%{3 => "four", "one" => :two}

地图中的键值对不遵循任何顺序(这就是为什么上面示例中的打印地图与创建的地图顺序不同)。

地图不对关键字类型施加任何限制:任何东西都可以成为地图中的关键字。作为键值结构,地图不允许重复键。密钥使用完全相等运算符(===)进行比较。如果在地图文字中定义了碰撞键,则以最后一个为准。

当键 - 值对中的键是原子时,key: value可以使用简写语法(如许多其他特殊形式),只要在末尾放置键值对即可:

iex> %{"hello" => "world", a: 1, b: 2}
%{:a => 1, :b => 2, "hello" => "world"}

地图中的键可通过此模块中的某些功能(如Map.get/3Map.fetch/2)或通过模块[]提供的语法来访问Access

iex> map = %{a: 1, b: 2}
iex> Map.fetch(map, :a)
{:ok, 1}
iex> map[:b]
2
iex> map["non_existing_key"]
nil

替代访问语法map.key[]地图具有:key关键字时一起提供; 注意,虽然map[key]将返回nil,如果map不包含keymap.key如果将募集map不包含关键:key

iex> map = %{foo: "bar", baz: "bong"}
iex> map.foo
"bar"
iex> map.non_existing_key
** (KeyError) key :non_existing_key not found in: %{baz: "bong", foo: "bar"}

地图可以在模式上匹配; 当地图位于模式匹配的左侧时,如果右侧的地图包含左侧的键并且其值与左侧的匹配,则匹配。这意味着空地图匹配每个地图。

iex> %{} = %{foo: "bar"}
%{foo: "bar"}
iex> %{a: a} = %{:a => 1, "b" => 2, [:c, :e, :e] => 3}
iex> a
1
iex> %{:c => 3} = %{:a => 1, 2 => :b}
** (MatchError) no match of right hand side value: %{2 => :b, :a => 1}

在写入地图文本时以及在匹配时,变量都可以用作映射键:

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

地图还支持特定的更新语法来更新存储在现有原子键下的值:

iex> map = %{one: 1, two: 2}
iex> %{map | one: "one"}
%{one: "one", two: 2}
iex> %{map | three: 3}
** (KeyError) key :three not found

使用地图的模块

该模块旨在提供执行特定于地图的操作(如访问键,更新值等)的功能。为了将地图作为集合进行遍历,开发人员应该使用Enum适用于各种数据类型的模块。

Kernel模块还提供了几个功能来处理地图:例如,Kernel.map_size/1了解地图中键值对的数量或Kernel.is_map/1知道某个术语是否为地图。

类型

key()value()

功能

delete(map, key)

删除map对于一个特定的key

drop(map, keys)

丢弃给定keysmap

equal?(map1, map2)

检查两个映射是否相等

fetch(map, key)

获取特定key在给定的map

fetch!(map, key)

获取特定key在给定的map,如果map不包含key

from_struct(struct)

转换struct地图

get(map, key, default \ nil)

获取指定的keymap

get_and_update(map, key, fun)

获取key并更新它,在一次传递中

get_and_update!(map, key, fun)

获取key并更新它。如果没有key

get_lazy(map, key, fun)

获取指定的keymap

has_key?(map, key)

返回给定的key存在于给定的map

keys(map)

返回所有密钥。map

merge(map1, map2)

将两幅地图合并为一幅

merge(map1, map2, callback)

将两个映射合并为一个,通过给定的callback

new()

返回一个新的空映射。

new(enumerable)

创建一个地图。enumerable

new(enumerable, transform)

创建一个地图。enumerable通过给定的变换函数

pop(map, key, default \ nil)

返回并移除与keymap

pop_lazy(map, key, fun)

懒惰返回并删除与keyin 关联的值map

put(map, key, value)

放给valuekeymap

put_new(map, key, value)

使给定valuekey,除非该条目key中已存在map

put_new_lazy(map, key, fun)

除非已经存在,否则评估fun和放置结果keymapkey

replace(map, key, value)

改变下存储的值keyvalue,但前提是该条目key中已存在map

replace!(map, key, value)

类似于replace/3,但会引起KeyError如果映射中不存在密钥

split(map, keys)

获取与给定keysmap并将它们提取成一张单独的地图

take(map, keys)

返回密钥map所在的所有键值对的新映射keys

to_list(map)

转换map为列表

update(map, key, initial, fun)

更新keymap具有给定的函数

update!(map, key, fun)

更新key具有给定的函数

values(map)

从中返回所有值 map

key()

key() :: any

value()

value() :: any

delete(map, key)

delete(map, key) :: map

删除map特定条目key

如果key不存在,返回map没有变化。

实例

iex> Map.delete(%{a: 1, b: 2}, :a)
%{b: 2}
iex> Map.delete(%{b: 2}, :a)
%{b: 2}

编译器插入。

drop(map, keys)

drop(map, Enumerable.t) :: map

丢弃给定keysmap

如果keys包含不在的键,则map简单地忽略它们。

实例

iex> Map.drop(%{a: 1, b: 2, c: 3}, [:b, :d])
%{a: 1, c: 3}

equal?(map1, map2)

equal?(map, map) :: boolean

检查两个映射是否相等。

如果两个映射包含相同的键,而这些键包含相同的值,则认为它们是相等的。

实例

iex> Map.equal?(%{a: 1, b: 2}, %{b: 2, a: 1})
true
iex> Map.equal?(%{a: 1, b: 2}, %{b: 1, a: 2})
false

fetch(map, key)

fetch(map, key) :: {:ok, value} | :error

获取特定的值,key在给定的map

如果map包含给定keyvalue,则{:ok, value}返回。如果map不包含key:error则返回。

实例

iex> Map.fetch(%{a: 1}, :a)
{:ok, 1}
iex> Map.fetch(%{a: 1}, :b)
:error

编译器插入。

fetch!(map, key)

fetch!(map, key) :: value | no_return

获取key给定值中的特定值,map如果map不包含则返回错误值key

如果map包含给定key,则返回相应的值。如果map不包含keyKeyError则会引发异常。

实例

iex> Map.fetch!(%{a: 1}, :a)
1
iex> Map.fetch!(%{a: 1}, :b)
** (KeyError) key :b not found in: %{a: 1}

from_struct(struct)

from_struct(atom | struct) :: map

转换struct去地图。

它接受结构模块或结构本身,并简单地__struct__从给定结构或从给定模块生成的新结构中删除该字段。

defmodule User do
  defstruct [:name]
end

Map.from_struct(User)
#=> %{name: nil}

Map.from_struct(%User{name: "john"})
#=> %{name: "john"}

get(map, key, default \ nil)

get(map, key, value) :: value

获取特定的价值keymap

如果key出现在map值中value,则value返回。否则,default返回(nil除非另有说明)。

实例

iex> Map.get(%{}, :a)
nil
iex> Map.get(%{a: 1}, :a)
1
iex> Map.get(%{a: 1}, :b)
nil
iex> Map.get(%{a: 1}, :b, 3)
3

get_and_update(map, key, fun)

get_and_update(map, key, (value -> {get, value} | :pop)) :: {get, map} when get: term

获取key更新一下,一次就可以了。

funkeyin中的当前值调用map(或者nil如果key不存在map),并且必须返回一个两元素元组:“get”值(返回的值,可以在返回前操作)和新的值存储key在生成的新地图中。fun也可能会返回:pop,这意味着当前值将被移除map并返回(使得该函数的行为类似于Map.pop(map, key)

返回值是一个带有返回值“get”值的元组,fun以及一个带有更新值的新映射key

实例

iex> Map.get_and_update(%{a: 1}, :a, fn current_value ->
...>   {current_value, "new value!"}
...> end)
{1, %{a: "new value!"}}

iex> Map.get_and_update(%{a: 1}, :b, fn current_value ->
...>   {current_value, "new value!"}
...> end)
{nil, %{b: "new value!", a: 1}}

iex> Map.get_and_update(%{a: 1}, :a, fn _ -> :pop end)
{1, %{}}

iex> Map.get_and_update(%{a: 1}, :b, fn _ -> :pop end)
{nil, %{a: 1}}

get_and_update!(map, key, fun)

get_and_update!(map, key, (value -> {get, value})) ::
  {get, map} |
  no_return when get: term

从中获取价值key并进行更新。如果没有,则引发key

表现完全一样get_and_update/3,但KeyError如果key不存在则引发异常map

实例

iex> Map.get_and_update!(%{a: 1}, :a, fn current_value ->
...>   {current_value, "new value!"}
...> end)
{1, %{a: "new value!"}}

iex> Map.get_and_update!(%{a: 1}, :b, fn current_value ->
...>   {current_value, "new value!"}
...> end)
** (KeyError) key :b not found in: %{a: 1}

iex> Map.get_and_update!(%{a: 1}, :a, fn _ ->
...>   :pop
...> end)
{1, %{}}

get_lazy(map, key, fun)

get_lazy(map, key, (() -> value)) :: value

获取特定的价值keymap

如果key存在于map有价值value,然后value会被归还。否则,fun计算并返回其结果。

如果默认值计算成本很高,或者通常很难设置和重新删除,这是非常有用的。

实例

iex> map = %{a: 1}
iex> fun = fn ->
...>   # some expensive operation here
...>   13
...> end
iex> Map.get_lazy(map, :a, fun)
1
iex> Map.get_lazy(map, :b, fun)
13

has_key?(map, key)

has_key?(map, key) :: boolean

返回给定中是否key存在给定值map

实例

iex> Map.has_key?(%{a: 1}, :a)
true
iex> Map.has_key?(%{a: 1}, :b)
false

编译器插入。

keys(map)

keys(map) :: [key]

从中返回所有密钥map

实例

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

merge(map1, map2)

merge(map, map) :: map

将两幅地图合并为一幅。

所有密钥map2将被添加到map1,覆盖任何现有密钥(即,map2“优先于”中的密钥map1)。

如果你有一个结构,并且你想将一组键合并到结构中,不要使用这个函数,因为它会将右侧的所有键合并到结构中,即使键不是结构的一部分。相反,使用Kernel.struct/2

实例

iex> Map.merge(%{a: 1, b: 2}, %{a: 3, d: 4})
%{a: 3, b: 2, d: 4}

merge(map1, map2, callback)

merge(map, map, (key, value, value -> value)) :: map

将两张地图合并为一张,通过给定的解决冲突callback

所有密钥map2将被添加到map1。当有重复的键时,将调用给定的函数; 它的参数是key(重复键),value1keyin 的值map1)和value2keyin 的值map2)。返回的值将callback用作key结果映射中的值。

实例

iex> Map.merge(%{a: 1, b: 2}, %{a: 3, d: 4}, fn _k, v1, v2 ->
...>   v1 + v2
...> end)
%{a: 4, b: 2, d: 4}

new()

new() :: map

返回一个新的空地图。

实例

iex> Map.new
%{}

new(enumerable)

new(Enumerable.t) :: map

从一个地图创建一个地图enumerable

重复的键被移除;最新的键占上风。

实例

iex> Map.new([{:b, 1}, {:a, 2}])
%{a: 2, b: 1}
iex> Map.new([a: 1, a: 2, a: 3])
%{a: 3}

new(enumerable, transform)

new(Enumerable.t, (term -> {key, value})) :: map

enumerable通过给定的转换函数创建一个映射。

重复的密钥被删除; 最新的一个流行。

实例

iex> Map.new([:a, :b], fn x -> {x, x} end)
%{a: :a, b: :b}

pop(map, key, default \ nil)

pop(map, key, value) :: {value, map}

返回并删除与keyin 关联的值map

如果key存在于map值中value{value, new_map}则返回从中new_map移除的结果。如果不存在,则返回。keymapkeymap{default, map}

实例

iex> Map.pop(%{a: 1}, :a)
{1, %{}}
iex> Map.pop(%{a: 1}, :b)
{nil, %{a: 1}}
iex> Map.pop(%{a: 1}, :b, 3)
{3, %{a: 1}}

pop_lazy(map, key, fun)

pop_lazy(map, key, (() -> value)) :: {value, map}

懒惰返回并删除与keyin 关联的值map

如果key存在于map值中value{value, new_map}则返回从中new_map移除的结果。如果不存在,返回,申请的结果在哪里。keymapkeymap{fun_result, map}fun_resultfun

如果默认值的计算非常昂贵,或者通常难以设置和拆卸,这很有用。

实例

iex> map = %{a: 1}
iex> fun = fn ->
...>   # some expensive operation here
...>   13
...> end
iex> Map.pop_lazy(map, :a, fun)
{1, %{}}
iex> Map.pop_lazy(map, :b, fun)
{13, %{a: 1}}

put(map, key, value)

put(map, key, value) :: map

放给valuekeymap

实例

iex> Map.put(%{a: 1}, :b, 2)
%{a: 1, b: 2}
iex> Map.put(%{a: 1, b: 2}, :a, 3)
%{a: 3, b: 2}

编译器插入。

put_new(map, key, value)

put_new(map, key, value) :: map

使给定valuekey,除非该条目key中已存在map

实例

iex> Map.put_new(%{a: 1}, :b, 2)
%{a: 1, b: 2}
iex> Map.put_new(%{a: 1, b: 2}, :a, 3)
%{a: 1, b: 2}

put_new_lazy(map, key, fun)

put_new_lazy(map, key, (() -> value)) :: map

除非已经存在,否则评估fun和放置结果。keymapkey

如果您想要计算要放入的值(key如果该值key尚未存在)(例如,该值计算昂贵或通常难以设置和拆卸),此功能非常有用。

实例

iex> map = %{a: 1}
iex> fun = fn ->
...>   # some expensive operation here
...>   3
...> end
iex> Map.put_new_lazy(map, :a, fun)
%{a: 1}
iex> Map.put_new_lazy(map, :b, fun)
%{a: 1, b: 3}

replace(map, key, value)

replace(map, key, value) :: map

改变下存储的值keyvalue,但前提是该条目key已经存在map

实例

iex> Map.replace(%{a: 1}, :b, 2)
%{a: 1}
iex> Map.replace(%{a: 1, b: 2}, :a, 3)
%{a: 3, b: 2}

replace!(map, key, value)

replace!(map, key, value) :: map

类似于replace/3,但KeyError如果密钥不存在于地图中,则会提高。

实例

iex> Map.replace!(%{a: 1, b: 2}, :a, 3)
%{a: 3, b: 2}
iex> Map.replace!(%{a: 1}, :b, 2)
** (KeyError) key :b not found in: %{a: 1}

编译器插入。

split(map, keys)

split(map, Enumerable.t) :: {map, map}

获取与给定的相对应的所有条目keysmap并将它们提取到单独的地图中。

返回带有新映射的元组和带有移除键的旧映射。

没有条目的键map被忽略。

实例

iex> Map.split(%{a: 1, b: 2, c: 3}, [:a, :c, :e])
{%{a: 1, c: 3}, %{b: 2}}

take(map, keys)

take(map, Enumerable.t) :: map

返回密钥map所在的所有键值对的新映射keys

如果keys包含不在的键,则map简单地忽略它们。

实例

iex> Map.take(%{a: 1, b: 2, c: 3}, [:a, :c, :e])
%{a: 1, c: 3}

to_list(map)

to_list(map) :: [{term, term}]

转换map为列表。

映射中的每个键值对都会转换为{key, value}结果列表中的两元素元组。

实例

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

update(map, key, initial, fun)

update(map, key, value, (value -> value)) :: map

更新keymap用给定的函数。

如果key存在于map值中valuefun则用参数调用value并将其结果用作新的值key。如果key不存在mapinitial则插入为值key。初始值不会通过更新功能。

实例

iex> Map.update(%{a: 1}, :a, 13, &(&1 * 2))
%{a: 2}
iex> Map.update(%{a: 1}, :b, 11, &(&1 * 2))
%{a: 1, b: 11}

update!(map, key, fun)

update!(map, key, (value -> value)) :: map

更新key用给定的函数。

如果key存在于map值中valuefun则用参数调用value并将其结果用作新的值key。如果key不存在mapKeyError则会引发异常。

实例

iex> Map.update!(%{a: 1}, :a, &(&1 * 2))
%{a: 2}

iex> Map.update!(%{a: 1}, :b, &(&1 * 2))
** (KeyError) key :b not found in: %{a: 1}

values(map)

values(map) :: [value]

从中返回所有值map

实例

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

地图 | Map相关

Elixir 1.5

Elixir 基于 Erlang 虚拟机的函数式、面向并行,是一种较好的编程语言。它以 Erlang 为基础,支持分布式、高容错、实时应用程序的开发。

主页 https://elixir-lang.org/
源码 https://github.com/elixir-lang/elixir
版本 1.5
发布版本 1.5.2