Elixir v1.5.0 Map View Source
A set of functions for working with maps.
Maps are the “go to” key-value data structure in Elixir. Maps can be created
with the %{}
syntax, and key-value pairs can be expressed as key => value
:
iex> %{}
%{}
iex> %{"one" => :two, 3 => "four"}
%{3 => "four", "one" => :two}
Key-value pairs in a map do not follow any order (that’s why the printed map in the example above has a different order than the map that was created).
Maps do not impose any restriction on the key type: anything can be a key in a
map. As a key-value structure, maps do not allow duplicated keys. Keys are
compared using the exact-equality operator (===
). If colliding keys are defined
in a map literal, the last one prevails.
When the key in a key-value pair is an atom, the key: value
shorthand syntax
can be used (as in many other special forms), provided key-value pairs are put at
the end:
iex> %{"hello" => "world", a: 1, b: 2}
%{:a => 1, :b => 2, "hello" => "world"}
Keys in maps can be accessed through some of the functions in this module
(such as Map.get/3
or Map.fetch/2
) or through the []
syntax provided by
the Access
module:
iex> map = %{a: 1, b: 2}
iex> Map.fetch(map, :a)
{:ok, 1}
iex> map[:b]
2
iex> map["non_existing_key"]
nil
The alternative access syntax map.key
is provided alongside []
when the
map has a :key
key; note that while map[key]
will return nil
if map
doesn’t contain key
, map.key
will raise if map
doesn’t contain
the key :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"}
Maps can be pattern matched on; when a map is on the left-hand side of a pattern match, it will match if the map on the right-hand side contains the keys on the left-hand side and their values match the ones on the left-hand side. This means that an empty map matches every map.
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}
Variables can be used as map keys both when writing map literals as well as when matching:
iex> n = 1
1
iex> %{n => :one}
%{1 => :one}
iex> %{^n => :one} = %{1 => :one, 2 => :two, 3 => :three}
%{1 => :one, 2 => :two, 3 => :three}
Maps also support a specific update syntax to update the value stored under existing atom keys:
iex> map = %{one: 1, two: 2}
iex> %{map | one: "one"}
%{one: "one", two: 2}
iex> %{map | three: 3}
** (KeyError) key :three not found
Modules to work with maps
This module aims to provide functions that perform operations specific to maps
(like accessing keys, updating values, and so on). For traversing maps as
collections, developers should use the Enum
module that works across a
variety of data types.
The Kernel
module also provides a few functions to work with maps: for
example, Kernel.map_size/1
to know the number of key-value pairs in a map or
Kernel.is_map/1
to know if a term is a map.
Link to this section Summary
Functions
Deletes the entry in map
for a specific key
Drops the given keys
from map
Checks if two maps are equal
Fetches the value for a specific key
in the given map
Fetches the value for a specific key
in the given map
, erroring out if
map
doesn’t contain key
Converts a struct
to map
Gets the value for a specific key
in map
Gets the value from key
and updates it, all in one pass
Gets the value from key
and updates it. Raises if there is no key
Gets the value for a specific key
in map
Returns whether the given key
exists in the given map
Returns all keys from map
Merges two maps into one
Merges two maps into one, resolving conflicts through the given callback
Returns a new empty map
Creates a map from an enumerable
Creates a map from an enumerable
via the given transformation function
Returns and removes the value associated with key
in map
Lazily returns and removes the value associated with key
in map
Puts the given value
under key
in map
Puts the given value
under key
unless the entry key
already exists in map
Evaluates fun
and puts the result under key
in map
unless key
is already present
Alters the value stored under key
to value
, but only
if the entry key
already exists in map
Takes all entries corresponding to the given keys
in map
and extracts
them into a separate map
Returns a new map with all the key-value pairs in map
where the key
is in keys
Converts map
to a list
Updates the key
in map
with the given function
Updates key
with the given function
Returns all values from map
Link to this section Types
Link to this section Functions
Deletes the entry in map
for a specific key
.
If the key
does not exist, returns map
unchanged.
Examples
iex> Map.delete(%{a: 1, b: 2}, :a)
%{b: 2}
iex> Map.delete(%{b: 2}, :a)
%{b: 2}
Inlined by the compiler.
Drops the given keys
from map
.
If keys
contains keys that are not in map
, they’re simply ignored.
Examples
iex> Map.drop(%{a: 1, b: 2, c: 3}, [:b, :d])
%{a: 1, c: 3}
Checks if two maps are equal.
Two maps are considered to be equal if they contain the same keys and those keys contain the same values.
Examples
iex> Map.equal?(%{a: 1, b: 2}, %{b: 2, a: 1})
true
iex> Map.equal?(%{a: 1, b: 2}, %{b: 1, a: 2})
false
Fetches the value for a specific key
in the given map
.
If map
contains the given key
with value value
, then {:ok, value}
is
returned. If map
doesn’t contain key
, :error
is returned.
Examples
iex> Map.fetch(%{a: 1}, :a)
{:ok, 1}
iex> Map.fetch(%{a: 1}, :b)
:error
Inlined by the compiler.
Fetches the value for a specific key
in the given map
, erroring out if
map
doesn’t contain key
.
If map
contains the given key
, the corresponding value is returned. If
map
doesn’t contain key
, a KeyError
exception is raised.
Examples
iex> Map.fetch!(%{a: 1}, :a)
1
iex> Map.fetch!(%{a: 1}, :b)
** (KeyError) key :b not found in: %{a: 1}
Converts a struct
to map.
It accepts the struct module or a struct itself and
simply removes the __struct__
field from the given struct
or from a new struct generated from the given module.
Example
defmodule User do
defstruct [:name]
end
Map.from_struct(User)
#=> %{name: nil}
Map.from_struct(%User{name: "john"})
#=> %{name: "john"}
Gets the value for a specific key
in map
.
If key
is present in map
with value value
, then value
is
returned. Otherwise, default
is returned (which is nil
unless
specified otherwise).
Examples
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
Gets the value from key
and updates it, all in one pass.
fun
is called with the current value under key
in map
(or nil
if key
is not present in map
) and must return a two-element tuple: the “get” value
(the retrieved value, which can be operated on before being returned) and the
new value to be stored under key
in the resulting new map. fun
may also
return :pop
, which means the current value shall be removed from map
and
returned (making this function behave like Map.pop(map, key)
.
The returned value is a tuple with the “get” value returned by
fun
and a new map with the updated value under key
.
Examples
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}}
Gets the value from key
and updates it. Raises if there is no key
.
Behaves exactly like get_and_update/3
, but raises a KeyError
exception if
key
is not present in map
.
Examples
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, %{}}
Gets the value for a specific key
in map
.
If key
is present in map
with value value
, then value
is
returned. Otherwise, fun
is evaluated and its result is returned.
This is useful if the default value is very expensive to calculate or generally difficult to setup and teardown again.
Examples
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
Returns whether the given key
exists in the given map
.
Examples
iex> Map.has_key?(%{a: 1}, :a)
true
iex> Map.has_key?(%{a: 1}, :b)
false
Inlined by the compiler.
Merges two maps into one.
All keys in map2
will be added to map1
, overriding any existing one
(i.e., the keys in map2
“have precedence” over the ones in map1
).
If you have a struct and you would like to merge a set of keys into the
struct, do not use this function, as it would merge all keys on the right
side into the struct, even if the key is not part of the struct. Instead,
use Kernel.struct/2
.
Examples
iex> Map.merge(%{a: 1, b: 2}, %{a: 3, d: 4})
%{a: 3, b: 2, d: 4}
Merges two maps into one, resolving conflicts through the given callback
.
All keys in map2
will be added to map1
. The given function will be invoked
when there are duplicate keys; its arguments are key
(the duplicate key),
value1
(the value of key
in map1
), and value2
(the value of key
in
map2
). The value returned by callback
is used as the value under key
in
the resulting map.
Examples
iex> Map.merge(%{a: 1, b: 2}, %{a: 3, d: 4}, fn _k, v1, v2 ->
...> v1 + v2
...> end)
%{a: 4, b: 2, d: 4}
Creates a map from an enumerable
.
Duplicated keys are removed; the latest one prevails.
Examples
iex> Map.new([{:b, 1}, {:a, 2}])
%{a: 2, b: 1}
iex> Map.new([a: 1, a: 2, a: 3])
%{a: 3}
new(Enumerable.t(), (term() -> {key(), value()})) :: map()
Creates a map from an enumerable
via the given transformation function.
Duplicated keys are removed; the latest one prevails.
Examples
iex> Map.new([:a, :b], fn x -> {x, x} end)
%{a: :a, b: :b}
Returns and removes the value associated with key
in map
.
If key
is present in map
with value value
, {value, new_map}
is
returned where new_map
is the result of removing key
from map
. If key
is not present in map
, {default, map}
is returned.
Examples
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}}
Lazily returns and removes the value associated with key
in map
.
If key
is present in map
with value value
, {value, new_map}
is
returned where new_map
is the result of removing key
from map
. If key
is not present in map
, {fun_result, map}
is returned, where fun_result
is the result of applying fun
.
This is useful if the default value is very expensive to calculate or generally difficult to setup and teardown again.
Examples
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}}
Puts the given value
under key
in map
.
Examples
iex> Map.put(%{a: 1}, :b, 2)
%{a: 1, b: 2}
iex> Map.put(%{a: 1, b: 2}, :a, 3)
%{a: 3, b: 2}
Inlined by the compiler.
Puts the given value
under key
unless the entry key
already exists in map
.
Examples
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}
Evaluates fun
and puts the result under key
in map
unless key
is already present.
This function is useful in case you want to compute the value to put under
key
only if key
is not already present (e.g., the value is expensive to
calculate or generally difficult to setup and teardown again).
Examples
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}
Alters the value stored under key
to value
, but only
if the entry key
already exists in map
.
Examples
iex> Map.replace(%{a: 1}, :b, 2)
%{a: 1}
iex> Map.replace(%{a: 1, b: 2}, :a, 3)
%{a: 3, b: 2}
Similar to replace/3
, but will raise a KeyError
if the key does not exist in the map.
Examples
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}
Inlined by the compiler.
Takes all entries corresponding to the given keys
in map
and extracts
them into a separate map.
Returns a tuple with the new map and the old map with removed keys.
Keys for which there are no entries in map
are ignored.
Examples
iex> Map.split(%{a: 1, b: 2, c: 3}, [:a, :c, :e])
{%{a: 1, c: 3}, %{b: 2}}
Returns a new map with all the key-value pairs in map
where the key
is in keys
.
If keys
contains keys that are not in map
, they’re simply ignored.
Examples
iex> Map.take(%{a: 1, b: 2, c: 3}, [:a, :c, :e])
%{a: 1, c: 3}
Converts map
to a list.
Each key-value pair in the map is converted to a two-element tuple {key,
value}
in the resulting list.
Examples
iex> Map.to_list(%{a: 1})
[a: 1]
iex> Map.to_list(%{1 => 2})
[{1, 2}]
Updates the key
in map
with the given function.
If key
is present in map
with value value
, fun
is invoked with
argument value
and its result is used as the new value of key
. If key
is
not present in map
, initial
is inserted as the value of key
. The initial
value will not be passed through the update function.
Examples
iex> Map.update(%{a: 1}, :a, 13, &(&1 * 2))
%{a: 2}
iex> Map.update(%{a: 1}, :b, 11, &(&1 * 2))
%{a: 1, b: 11}
Updates key
with the given function.
If key
is present in map
with value value
, fun
is invoked with
argument value
and its result is used as the new value of key
. If key
is
not present in map
, a KeyError
exception is raised.
Examples
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}