Elixir v1.6.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 fun

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

Link to this function delete(map, key) View Source
delete(map(), key()) :: map()

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}
Link to this function equal?(map1, map2) View Source
equal?(map(), map()) :: boolean()

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
Link to this function fetch(map, key) View Source
fetch(map(), key()) :: {:ok, value()} | :error

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.

Link to this function fetch!(map, key) View Source
fetch!(map(), key()) :: value() | no_return()

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}
Link to this function from_struct(struct) View Source
from_struct(atom() | struct()) :: map()

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"}
Link to this function get(map, key, default \\ nil) View Source
get(map(), key(), value()) :: value()

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
Link to this function get_and_update(map, key, fun) View Source
get_and_update(map(), key(), (value() -> {get, value()} | :pop)) ::
  {get, map()}
when get: term()

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}}
Link to this function get_and_update!(map, key, fun) View Source
get_and_update!(map(), key(), (value() -> {get, value()} | :pop)) ::
  {get, map()} | no_return()
when get: term()

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, %{}}
Link to this function get_lazy(map, key, fun) View Source
get_lazy(map(), key(), (() -> value())) :: value()

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
Link to this function has_key?(map, key) View Source
has_key?(map(), key()) :: boolean()

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.

Returns all keys from map.

Examples

iex> Map.keys(%{a: 1, b: 2})
[:a, :b]
Link to this function merge(map1, map2) View Source
merge(map(), map()) :: map()

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}
Link to this function merge(map1, map2, fun) View Source
merge(map(), map(), (key(), value(), value() -> value())) :: map()

Merges two maps into one, resolving conflicts through the given fun.

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 fun 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}

Returns a new empty map.

Examples

iex> Map.new
%{}

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}
Link to this function new(enumerable, transform) View Source
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}
Link to this function pop(map, key, default \\ nil) View Source
pop(map(), key(), value()) :: {value(), map()}

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}}
Link to this function pop_lazy(map, key, fun) View Source
pop_lazy(map(), key(), (() -> value())) :: {value(), map()}

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}}
Link to this function put(map, key, value) View Source
put(map(), key(), value()) :: map()

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.

Link to this function put_new(map, key, value) View Source
put_new(map(), key(), value()) :: map()

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}
Link to this function put_new_lazy(map, key, fun) View Source
put_new_lazy(map(), key(), (() -> value())) :: map()

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}
Link to this function replace!(map, key, value) View Source
replace!(map(), key(), value()) :: map()

Alters the value stored under key to value, but only if the entry key already exists in map.

If key is not present in map, a KeyError exception is raised.

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.

Link to this function split(map, keys) View Source
split(map(), Enumerable.t()) :: {map(), map()}

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}
Link to this function to_list(map) View Source
to_list(map()) :: [{term(), term()}]

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}]
Link to this function update(map, key, initial, fun) View Source
update(map(), key(), value(), (value() -> value())) :: map()

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}
Link to this function update!(map, key, fun) View Source
update!(map(), key(), (value() -> value())) :: map()

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}
Link to this function values(map) View Source
values(map()) :: [value()]

Returns all values from map.

Examples

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