Spec-Zone.ru › Elixir 1.5

Карта

Набор функций для работы с картами.

Карты — это основная структура данных ключ-значение в 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/3 или Map.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 не содержит key, map.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)

Удаляет заданные keys из map

equal?(map1, map2)

Проверяет, равны ли две карты

fetch(map, key)

Извлекает значение для определённого key в заданной map

fetch!(map, key)

Извлекает значение для определённого key в заданной map, вызывая ошибку, если map не содержит key

from_struct(struct)

Преобразует struct в карту

get(map, key, default \\ nil)

Получает значение для определённого key в map

get_and_update(map, key, fun)

Получает значение из key и обновляет его, всё в одном проходе

get_and_update!(map, key, fun)

Получает значение из key и обновляет его. Вызывает исключение, если key отсутствует

get_lazy(map, key, fun)

Получает значение для определённого key в map

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)

Возвращает и удаляет значение, связанное с key в map

pop_lazy(map, key, fun)

Лениво возвращает и удаляет значение, связанное с key в map

put(map, key, value)

Добавляет заданное value под key в map

put_new(map, key, value)

Добавляет заданное value под key только если запись key ещё не существует в map

put_new_lazy(map, key, fun)

Вычисляет fun и добавляет результат под key в map только если key ещё не существует

replace(map, key, value)

Изменяет значение, хранящееся под key, на value, но только если запись key уже существует в map

replace!(map, key, value)

Аналогично replace/3, но вызовет исключение KeyError, если ключ не существует в карте

split(map, keys)

Берёт все записи, соответствующие заданным keys в map и извлекает их в отдельную карту

take(map, keys)

Возвращает новую карту со всеми парами ключ-значение в map, где ключ находится в keys

to_list(map)

Преобразует map в список

update(map, key, initial, fun)

Обновляет key в map с помощью заданной функции

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()

Удаляет заданные keys из map.

Если 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 содержит данный key со значением value, то возвращается {: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 не содержит key, генерируется исключение KeyError.

Примеры

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()

Получает значение для определенного key в map.

Если 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 и обновляет его, все в одном проходе.

fun вызывается со текущим значением под key в map (или nil если key не присутствует в map) и должно вернуть кортеж из двух элементов: значение «получить» (полученное значение, которое можно обработать перед возвратом) и новое значение, которое должно храниться под key в результирующей новой карте. fun также может вернуть :pop, что означает, что текущее значение должно быть удалено из map и возвращено (что делает эту функцию похожей на Map.pop(map, key)).

Возвращаемое значение — это кортеж со значением «получить», возвращенным 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()

Получает значение для определенного key в map.

Если 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 (дублирующий ключ), value1 (значение key в map1), и value2 (значение key в 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()}

Возвращает и удаляет значение, связанное с key в map.

Если key присутствует в map со значением value, возвращается {value, new_map}, где new_map — результат удаления key из map. Если key не присутствует в map, возвращается {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()}

Лениво возвращает и удаляет значение, связанное с key в map.

Если key присутствует в map со значением value, возвращается {value, new_map}, где new_map — результат удаления key из map. Если key не присутствует в map, возвращается {fun_result, map}, где fun_result — результат применения fun.

Это полезно, если значение по умолчанию очень сложно вычислить или его трудно настроить и заново демонтировать.

Примеры

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()

Размещает заданное value под key в map.

Примеры

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()

Размещает заданное value под key, если запись 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 и размещает результат под key в map, если key ещё не существует.

Эта функция полезна в случае, если вы хотите вычислить значение, подлежащее размещению под 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()

Изменяет значение, хранящееся под key, на value, только если запись 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()}

Берет все записи, соответствующие заданным keys в map и извлекает их в отдельную карту.

Возвращает кортеж с новой картой и старой картой с удаленными ключами.

Ключи, для которых нет записей в 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()

Обновляет key в map с помощью заданной функции.

Если key присутствует в map со значением value, fun вызывается с аргументом value, и результат используется в качестве нового значения key. Если key отсутствует в map, initial вставляется в качестве значения 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 со значением value, fun вызывается с аргументом value и результат используется в качестве нового значения key. Если key отсутствует в map, возникает исключение KeyError.

Примеры

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]

© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.5.3/Map.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API