Карта
Набор функций для работы с картами.
Многие функции для карт, которые реализуют протокол Enumerable, находятся в модуле Enum. Кроме того, следующие функции для карт находятся в Kernel:
Карты — это основная структура данных "ключ-значение" в Elixir. Карты могут быть созданы с помощью синтаксиса %{}, а пары "ключ-значение" могут быть выражены как key => value:
iex> %{}
%{}
iex> %{"one" => :two, 3 => "four"}
%{3 => "four", "one" => :two} Пары "ключ-значение" в карте не следуют никакому порядку (поэтому напечатанная карта в примере выше имеет другой порядок, чем карта, которая была создана).
Карты не накладывают никаких ограничений на тип ключа: чем угодно может быть ключ в карте. Как структура "ключ-значение", карты не допускают дублирования ключей. Ключи сравниваются с помощью оператора точного равенства (===/2). Если в литерале карты определены коллидирующие ключи, преобладает последний.
Когда ключ в паре "ключ-значение" является атомом, можно использовать сокращённый синтаксис key: value (как и во многих других специальных формах), при условии, что пары "ключ-значение" помещаются в конце:
iex> %{"hello" => "world", a: 1, b: 2}
%{:a => 1, :b => 2, "hello" => "world"} К ключам в картах можно получить доступ через некоторые функции в этом модуле (например, Map.get/3 или Map.fetch/2) или через синтаксис map[], предоставляемый модулем 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. Обратите внимание, что в то время как 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"} Два синтаксиса для доступа к ключам раскрывают двойственную природу карт. Синтаксис map[key] используется для динамически созданных карт, которые могут иметь любой ключ любого типа. map.key используется с картами, содержащими предопределённый набор ключей-атомов, которые, как ожидается, всегда будут присутствовать. Структуры, определённые с помощью defstruct/1, являются одним примером таких "статичных карт", где ключи также могут быть проверены во время компиляции.
На картах можно выполнять сопоставление по образцу. Когда карта находится слева от оператора сопоставления по образцу, она будет соответствовать, если карта справа содержит ключи слева и их значения соответствуют значениям слева. Это означает, что пустая карта соответствует любой карте.
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 Функции в этом модуле, которые должны найти определённый ключ, работают за логарифмическое время. Это означает, что время, необходимое для поиска ключей, растёт по мере роста карты, но не прямо пропорционально размеру карты. По сравнению с поиском элемента в списке, он работает лучше, потому что списки имеют линейную сложность времени. Некоторые функции, такие как keys/1 и values/1, выполняются за линейное время, так как им нужно получить доступ к каждому элементу карты.
Краткое описание
Типы
Функции
- 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, fun)
Объединяет две карты в одну, разрешая конфликты с помощью заданной
fun.- 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.- 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()
Specs
key() :: any()
value()
Specs
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(), [key()]) :: 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()
Извлекает значение для определенного 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.
Если 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()} | :pop)) ::
{get, map()}
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, fun)
Спецификации
merge(map(), map(), (key(), value(), value() -> value())) :: map()
Объединяет два словаря в один, разрешая конфликты с помощью заданной fun.
Все ключи из map2 будут добавлены в map1. Данная функция будет вызвана при наличии дублирующих ключей; ее аргументы — key (дублирующий ключ), value1 (значение key в map1), и value2 (значение key в map2). Значение, возвращаемое fun, используется как значение под 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()
Создает словарь из перечислимого объекта.
Дублирующие ключи удаляются; сохраняется последнее значение.
Примеры
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() Создаёт словарь из перечислимого объекта с помощью заданной функции преобразования.
Дублирующие ключи удаляются; сохраняется последнее значение.
Примеры
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.
Если key не присутствует в map, генерируется исключение 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(), [key()]) :: {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(), [key()]) :: 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.9.4/Map.html