View Source Keyword (Elixir v1.12.0)

A keyword list is a list that consists exclusively of two-element tuples.

The first element of these tuples is known as the key, and it must be an atom. The second element, known as the value, can be any term.

Keywords are mostly used to work with optional values.

Examples

For example, the following is a keyword list:

[{:exit_on_close, true}, {:active, :once}, {:packet_size, 1024}]

Elixir provides a special and more concise syntax for keyword lists that looks like this:

[exit_on_close: true, active: :once, packet_size: 1024]

The two syntaxes are completely equivalent. Like atoms, keyword lists keys must be composed of Unicode characters such as letters, numbers, underscore, and @. If the keyword has a character that does not belong to the category above, such as spaces, you can wrap it in quotes:

iex> ["exit on close": true]
["exit on close": true]

Wrapping a keyword in quotes does not make it a string. Keyword lists keys are always atoms. If you use quotes around the key when quoting is not necessary, Elixir will warn.

Duplicate keys and ordering

A keyword may have duplicated keys so it is not strictly a key-value data type. However most of the functions in this module behave exactly as a key-value so they work similarly to the functions you would find in the Map module. For example, Keyword.get/3 will get the first entry matching the given key, regardless if duplicated entries exist. Similarly, Keyword.put/3 and Keyword.delete/2 ensure all duplicated entries for a given key are removed when invoked. Note, however, that keyword list operations need to traverse the whole list in order to find keys, so these operations are slower than their map counterparts.

A handful of functions exist to handle duplicated keys, for example, get_values/2 returns all values for a given key and delete_first/2 deletes just one of the existing entries.

Even though lists preserve the user ordering, the functions in Keyword do not guarantee any ordering. For example, if you invoke Keyword.put(opts, new_key, new_value), there is no guarantee to where new_key will be added (to the front, to the end, or anywhere else).

Given ordering is not guaranteed, it is not recommended to pattern match on keyword lists either. For example, a function such as:

def my_function([some_key: value, another_key: another_value])

will match

my_function([some_key: :foo, another_key: :bar])

but it won't match

my_function([another_key: :bar, some_key: :foo])

Most of the functions in this module work in linear time. This means that, the time it takes to perform an operation grows at the same rate as the length of the list.

Call syntax

When keyword lists are passed as the last argument to a function, the square brackets around the keyword list can be omitted. For example, the keyword list syntax:

String.split("1-0", "-", [trim: true, parts: 2])

can be written without the enclosing brackets whenever it is the last argument of a function call:

String.split("1-0", "-", trim: true, parts: 2)

Since tuples, lists, maps, and others are treated the same as function calls in Elixir syntax, this property is also available to them:

iex> {1, 2, foo: :bar}
{1, 2, [{:foo, :bar}]}

iex> [1, 2, foo: :bar]
[1, 2, {:foo, :bar}]

iex> %{1 => 2, foo: :bar}
%{1 => 2, :foo => :bar}

Link to this section Summary

Functions

Deletes the entries in the keyword list for a specific key.

Deletes the first entry in the keyword list for a specific key.

Drops the given keys from the keyword list.

Checks if two keywords are equal.

Fetches the value for a specific key and returns it in a tuple.

Fetches the value for specific key.

Gets the value for a specific key.

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.

Gets all values for a specific key.

Returns whether a given key exists in the given keywords.

Returns all keys from the keyword list.

Returns true if term is a keyword list; otherwise returns false.

Merges two keyword lists into one.

Merges two keyword lists into one.

Returns an empty keyword list, i.e. an empty list.

Creates a keyword list from an enumerable.

Creates a keyword list from an enumerable via the transformation function.

Returns the first value for key and removes all associated entries in the keyword list.

Returns the first value for key and removes all associated entries in the keyword list, raising if key is not present.

Returns and removes the first value associated with key in the keyword list.

Lazily returns and removes all values associated with key in the keyword list.

Returns all values for key and removes all associated entries in the keyword list.

Puts the given value under key.

Puts the given value under key unless the entry key already exists.

Evaluates fun and puts the result under key in keyword list unless key is already present.

Puts a value under key only if the key already exists in keywords.

Puts a value under key only if the key already exists in keywords.

Takes all entries corresponding to the given keys and extracts them into a separate keyword list.

Takes all entries corresponding to the given keys and returns them in a new keyword list.

Returns the keyword list itself.

Updates the key in keywords with the given function.

Updates the key with the given function.

Returns all values from the keyword list.

Link to this section Types

@type key() :: atom()
@type t() :: [{key(), value()}]
@type t(value) :: [{key(), value}]
@type value() :: any()

Link to this section Functions

@spec delete(t(), key()) :: t()

Deletes the entries in the keyword list for a specific key.

If the key does not exist, returns the keyword list unchanged. Use delete_first/2 to delete just the first entry in case of duplicated keys.

Examples

iex> Keyword.delete([a: 1, b: 2], :a)
[b: 2]
iex> Keyword.delete([a: 1, b: 2, a: 3], :a)
[b: 2]
iex> Keyword.delete([b: 2], :a)
[b: 2]
Link to this function

delete_first(keywords, key)

View Source
@spec delete_first(t(), key()) :: t()

Deletes the first entry in the keyword list for a specific key.

If the key does not exist, returns the keyword list unchanged.

Examples

iex> Keyword.delete_first([a: 1, b: 2, a: 3], :a)
[b: 2, a: 3]
iex> Keyword.delete_first([b: 2], :a)
[b: 2]
@spec drop(t(), [key()]) :: t()

Drops the given keys from the keyword list.

Duplicated keys are preserved in the new keyword list.

Examples

iex> Keyword.drop([a: 1, b: 2, c: 3], [:b, :d])
[a: 1, c: 3]
iex> Keyword.drop([a: 1, b: 2, b: 3, c: 3, a: 5], [:b, :d])
[a: 1, c: 3, a: 5]
@spec equal?(t(), t()) :: boolean()

Checks if two keywords are equal.

Two keywords are considered to be equal if they contain the same keys and those keys contain the same values.

Examples

iex> Keyword.equal?([a: 1, b: 2], [b: 2, a: 1])
true
iex> Keyword.equal?([a: 1, b: 2], [b: 1, a: 2])
false
iex> Keyword.equal?([a: 1, b: 2, a: 3], [b: 2, a: 3, a: 1])
true

Comparison between values is done with ===/3, which means integers are not equivalent to floats:

iex> Keyword.equal?([a: 1.0], [a: 1])
false
@spec fetch(t(), key()) :: {:ok, value()} | :error

Fetches the value for a specific key and returns it in a tuple.

If the key does not exist, returns :error.

Examples

iex> Keyword.fetch([a: 1], :a)
{:ok, 1}
iex> Keyword.fetch([a: 1], :b)
:error
@spec fetch!(t(), key()) :: value()

Fetches the value for specific key.

If key does not exist, a KeyError is raised.

Examples

iex> Keyword.fetch!([a: 1], :a)
1
iex> Keyword.fetch!([a: 1], :b)
** (KeyError) key :b not found in: [a: 1]
Link to this function

get(keywords, key, default \\ nil)

View Source
@spec get(t(), key(), value()) :: value()

Gets the value for a specific key.

If key does not exist, return the default value (nil if no default value).

If duplicated entries exist, the first one is returned. Use get_values/2 to retrieve all entries.

Examples

iex> Keyword.get([], :a)
nil
iex> Keyword.get([a: 1], :a)
1
iex> Keyword.get([a: 1], :b)
nil
iex> Keyword.get([a: 1], :b, 3)
3

With duplicated keys:

iex> Keyword.get([a: 1, a: 2], :a, 3)
1
iex> Keyword.get([a: 1, a: 2], :b, 3)
3
Link to this function

get_and_update(keywords, key, fun)

View Source
@spec get_and_update(
  t(),
  key(),
  (value() | nil -> {current_value, new_value :: value()} | :pop)
) :: {current_value, new_keywords :: t()}
when current_value: value()

Gets the value from key and updates it, all in one pass.

This fun argument receives the value of key (or nil if key is not present) and must return a two-element tuple: the current value (the retrieved value, which can be operated on before being returned) and the new value to be stored under key. The fun may also return :pop, implying the current value shall be removed from the keyword list and returned.

The returned value is a tuple with the current value returned by fun and a new keyword list with the updated value under key.

Examples

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

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

iex> Keyword.get_and_update([a: 1], :a, fn _ -> :pop end)
{1, []}

iex> Keyword.get_and_update([a: 1], :b, fn _ -> :pop end)
{nil, [a: 1]}
Link to this function

get_and_update!(keywords, key, fun)

View Source
@spec get_and_update!(
  t(),
  key(),
  (value() | nil -> {current_value, new_value :: value()} | :pop)
) :: {current_value, new_keywords :: t()}
when current_value: value()

Gets the value from key and updates it. Raises if there is no key.

This fun argument receives the value of key and must return a two-element tuple: the current value (the retrieved value, which can be operated on before being returned) and the new value to be stored under key.

The returned value is a tuple with the current value returned by fun and a new keyword list with the updated value under key.

Examples

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

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

iex> Keyword.get_and_update!([a: 1], :a, fn _ ->
...>   :pop
...> end)
{1, []}
Link to this function

get_lazy(keywords, key, fun)

View Source
@spec get_lazy(t(), key(), (() -> value())) :: value()

Gets the value for a specific key.

If key does not exist, lazily evaluates fun and returns its result.

This is useful if the default value is very expensive to calculate or generally difficult to setup and teardown again.

If duplicated entries exist, the first one is returned. Use get_values/2 to retrieve all entries.

Examples

iex> keyword = [a: 1]
iex> fun = fn ->
...>   # some expensive operation here
...>   13
...> end
iex> Keyword.get_lazy(keyword, :a, fun)
1
iex> Keyword.get_lazy(keyword, :b, fun)
13
Link to this function

get_values(keywords, key)

View Source
@spec get_values(t(), key()) :: [value()]

Gets all values for a specific key.

Examples

iex> Keyword.get_values([], :a)
[]
iex> Keyword.get_values([a: 1], :a)
[1]
iex> Keyword.get_values([a: 1, a: 2], :a)
[1, 2]
@spec has_key?(t(), key()) :: boolean()

Returns whether a given key exists in the given keywords.

Examples

iex> Keyword.has_key?([a: 1], :a)
true
iex> Keyword.has_key?([a: 1], :b)
false
@spec keys(t()) :: [key()]

Returns all keys from the keyword list.

Duplicated keys appear duplicated in the final list of keys.

Examples

iex> Keyword.keys(a: 1, b: 2)
[:a, :b]

iex> Keyword.keys(a: 1, b: 2, a: 3)
[:a, :b, :a]

iex> Keyword.keys([{:a, 1}, {"b", 2}, {:c, 3}])
** (ArgumentError) expected a keyword list, but an entry in the list is not a two-element tuple with an atom as its first element, got: {"b", 2}
@spec keyword?(term()) :: boolean()

Returns true if term is a keyword list; otherwise returns false.

Examples

iex> Keyword.keyword?([])
true
iex> Keyword.keyword?(a: 1)
true
iex> Keyword.keyword?([{Foo, 1}])
true
iex> Keyword.keyword?([{}])
false
iex> Keyword.keyword?([:key])
false
iex> Keyword.keyword?(%{})
false
Link to this function

merge(keywords1, keywords2)

View Source
@spec merge(t(), t()) :: t()

Merges two keyword lists into one.

All keys, including duplicated keys, given in keywords2 will be added to keywords1, overriding any existing one.

There are no guarantees about the order of keys in the returned keyword.

Examples

iex> Keyword.merge([a: 1, b: 2], [a: 3, d: 4])
[b: 2, a: 3, d: 4]

iex> Keyword.merge([a: 1, b: 2], [a: 3, d: 4, a: 5])
[b: 2, a: 3, d: 4, a: 5]

iex> Keyword.merge([a: 1], [2, 3])
** (ArgumentError) expected a keyword list as the second argument, got: [2, 3]
Link to this function

merge(keywords1, keywords2, fun)

View Source
@spec merge(t(), t(), (key(), value(), value() -> value())) :: t()

Merges two keyword lists into one.

All keys, including duplicated keys, given in keywords2 will be added to keywords1. The given function will be invoked to solve conflicts.

If keywords2 has duplicate keys, the given function will be invoked for each matching pair in keywords1.

There are no guarantees about the order of keys in the returned keyword.

Examples

iex> Keyword.merge([a: 1, b: 2], [a: 3, d: 4], fn _k, v1, v2 ->
...>   v1 + v2
...> end)
[b: 2, a: 4, d: 4]

iex> Keyword.merge([a: 1, b: 2], [a: 3, d: 4, a: 5], fn :a, v1, v2 ->
...>   v1 + v2
...> end)
[b: 2, a: 4, d: 4, a: 5]

iex> Keyword.merge([a: 1, b: 2, a: 3], [a: 3, d: 4, a: 5], fn :a, v1, v2 ->
...>   v1 + v2
...> end)
[b: 2, a: 4, d: 4, a: 8]

iex> Keyword.merge([a: 1, b: 2], [:a, :b], fn :a, v1, v2 ->
...>   v1 + v2
...> end)
** (ArgumentError) expected a keyword list as the second argument, got: [:a, :b]
@spec new() :: []

Returns an empty keyword list, i.e. an empty list.

Examples

iex> Keyword.new()
[]
@spec new(Enum.t()) :: t()

Creates a keyword list from an enumerable.

Duplicated entries are removed, the latest one prevails. Unlike Enum.into(enumerable, []), Keyword.new(enumerable) guarantees the keys are unique.

Examples

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

iex> Keyword.new([{:a, 1}, {:a, 2}, {:a, 3}])
[a: 3]
@spec new(Enum.t(), (term() -> {key(), value()})) :: t()

Creates a keyword list from an enumerable via the transformation function.

Duplicated entries are removed, the latest one prevails. Unlike Enum.into(enumerable, [], fun), Keyword.new(enumerable, fun) guarantees the keys are unique.

Examples

iex> Keyword.new([:a, :b], fn x -> {x, x} end)
[a: :a, b: :b]
Link to this function

pop(keywords, key, default \\ nil)

View Source
@spec pop(t(), key(), value()) :: {value(), t()}

Returns the first value for key and removes all associated entries in the keyword list.

It returns a tuple where the first element is the first value for key and the second element is a keyword list with all entries associated with key removed. If the key is not present in the keyword list, {default, keyword_list} is returned.

If you don't want to remove all the entries associated with key use pop_first/3 instead, that function will remove only the first entry.

Examples

iex> Keyword.pop([a: 1], :a)
{1, []}
iex> Keyword.pop([a: 1], :b)
{nil, [a: 1]}
iex> Keyword.pop([a: 1], :b, 3)
{3, [a: 1]}
iex> Keyword.pop([a: 1, a: 2], :a)
{1, []}
Link to this function

pop!(keywords, key)

View Source (since 1.10.0)
@spec pop!(t(), key()) :: {value(), t()}

Returns the first value for key and removes all associated entries in the keyword list, raising if key is not present.

This function behaves like pop/3, but raises in cases the key is not present in the given keywords.

Examples

iex> Keyword.pop!([a: 1], :a)
{1, []}
iex> Keyword.pop!([a: 1, a: 2], :a)
{1, []}
iex> Keyword.pop!([a: 1], :b)
** (KeyError) key :b not found in: [a: 1]
Link to this function

pop_first(keywords, key, default \\ nil)

View Source
@spec pop_first(t(), key(), value()) :: {value(), t()}

Returns and removes the first value associated with key in the keyword list.

Duplicated keys are not removed.

Examples

iex> Keyword.pop_first([a: 1], :a)
{1, []}
iex> Keyword.pop_first([a: 1], :b)
{nil, [a: 1]}
iex> Keyword.pop_first([a: 1], :b, 3)
{3, [a: 1]}
iex> Keyword.pop_first([a: 1, a: 2], :a)
{1, [a: 2]}
Link to this function

pop_lazy(keywords, key, fun)

View Source
@spec pop_lazy(t(), key(), (() -> value())) :: {value(), t()}

Lazily returns and removes all values associated with key in the keyword list.

This is useful if the default value is very expensive to calculate or generally difficult to setup and teardown again.

All duplicated keys are removed. See pop_first/3 for removing only the first entry.

Examples

iex> keyword = [a: 1]
iex> fun = fn ->
...>   # some expensive operation here
...>   13
...> end
iex> Keyword.pop_lazy(keyword, :a, fun)
{1, []}
iex> Keyword.pop_lazy(keyword, :b, fun)
{13, [a: 1]}
Link to this function

pop_values(keywords, key)

View Source (since 1.10.0)
@spec pop_values(t(), key()) :: {[value()], t()}

Returns all values for key and removes all associated entries in the keyword list.

It returns a tuple where the first element is a list of values for key and the second element is a keyword list with all entries associated with key removed. If the key is not present in the keyword list, {[], keyword_list} is returned.

If you don't want to remove all the entries associated with key use pop_first/3 instead, that function will remove only the first entry.

Examples

iex> Keyword.pop_values([a: 1], :a)
{[1], []}
iex> Keyword.pop_values([a: 1], :b)
{[], [a: 1]}
iex> Keyword.pop_values([a: 1, a: 2], :a)
{[1, 2], []}
Link to this function

put(keywords, key, value)

View Source
@spec put(t(), key(), value()) :: t()

Puts the given value under key.

If a previous value is already stored, all entries are removed and the value is overridden.

Examples

iex> Keyword.put([a: 1], :b, 2)
[b: 2, a: 1]
iex> Keyword.put([a: 1, b: 2], :a, 3)
[a: 3, b: 2]
iex> Keyword.put([a: 1, b: 2, a: 4], :a, 3)
[a: 3, b: 2]
Link to this function

put_new(keywords, key, value)

View Source
@spec put_new(t(), key(), value()) :: t()

Puts the given value under key unless the entry key already exists.

Examples

iex> Keyword.put_new([a: 1], :b, 2)
[b: 2, a: 1]
iex> Keyword.put_new([a: 1, b: 2], :a, 3)
[a: 1, b: 2]
Link to this function

put_new_lazy(keywords, key, fun)

View Source
@spec put_new_lazy(t(), key(), (() -> value())) :: t()

Evaluates fun and puts the result under key in keyword list unless key is already present.

This is useful if the value is very expensive to calculate or generally difficult to setup and teardown again.

Examples

iex> keyword = [a: 1]
iex> fun = fn ->
...>   # some expensive operation here
...>   3
...> end
iex> Keyword.put_new_lazy(keyword, :a, fun)
[a: 1]
iex> Keyword.put_new_lazy(keyword, :b, fun)
[b: 3, a: 1]
Link to this function

replace(keywords, key, value)

View Source (since 1.11.0)
@spec replace(t(), key(), value()) :: t()

Puts a value under key only if the key already exists in keywords.

In the case a value is stored multiple times in the keyword list, later occurrences are removed.

Examples

iex> Keyword.replace([a: 1, b: 2, a: 4], :a, 3)
[a: 3, b: 2]

iex> Keyword.replace([a: 1], :b, 2)
[a: 1]
Link to this function

replace!(keywords, key, value)

View Source (since 1.5.0)
@spec replace!(t(), key(), value()) :: t()

Puts a value under key only if the key already exists in keywords.

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

Examples

iex> Keyword.replace!([a: 1, b: 2, a: 3], :a, :new)
[a: :new, b: 2]
iex> Keyword.replace!([a: 1, b: 2, c: 3, b: 4], :b, :new)
[a: 1, b: :new, c: 3]

iex> Keyword.replace!([a: 1], :b, 2)
** (KeyError) key :b not found in: [a: 1]
@spec split(t(), [key()]) :: {t(), t()}

Takes all entries corresponding to the given keys and extracts them into a separate keyword list.

Returns a tuple with the new list and the old list with removed keys.

Keys for which there are no entries in the keyword list are ignored.

Entries with duplicated keys end up in the same keyword list.

Examples

iex> Keyword.split([a: 1, b: 2, c: 3], [:a, :c, :e])
{[a: 1, c: 3], [b: 2]}
iex> Keyword.split([a: 1, b: 2, c: 3, a: 4], [:a, :c, :e])
{[a: 1, c: 3, a: 4], [b: 2]}
@spec take(t(), [key()]) :: t()

Takes all entries corresponding to the given keys and returns them in a new keyword list.

Duplicated keys are preserved in the new keyword list.

Examples

iex> Keyword.take([a: 1, b: 2, c: 3], [:a, :c, :e])
[a: 1, c: 3]
iex> Keyword.take([a: 1, b: 2, c: 3, a: 5], [:a, :c, :e])
[a: 1, c: 3, a: 5]
@spec to_list(t()) :: t()

Returns the keyword list itself.

Examples

iex> Keyword.to_list(a: 1)
[a: 1]
Link to this function

update(keywords, key, default, fun)

View Source
@spec update(
  t(),
  key(),
  default :: value(),
  (existing_value :: value() -> new_value :: value())
) :: t()

Updates the key in keywords with the given function.

If the key does not exist, it inserts the given default value.

If there are duplicated keys, they are all removed and only the first one is updated.

The default value will not be passed through the update function.

Examples

iex> Keyword.update([a: 1], :a, 13, fn existing_value -> existing_value * 2 end)
[a: 2]

iex> Keyword.update([a: 1, a: 2], :a, 13, fn existing_value -> existing_value * 2 end)
[a: 2]

iex> Keyword.update([a: 1], :b, 11, fn existing_value -> existing_value * 2 end)
[a: 1, b: 11]
Link to this function

update!(keywords, key, fun)

View Source
@spec update!(t(), key(), (current_value :: value() -> new_value :: value())) :: t()

Updates the key with the given function.

If the key does not exist, raises KeyError.

If there are duplicated keys, they are all removed and only the first one is updated.

Examples

iex> Keyword.update!([a: 1, b: 2, a: 3], :a, &(&1 * 2))
[a: 2, b: 2]
iex> Keyword.update!([a: 1, b: 2, c: 3], :b, &(&1 * 2))
[a: 1, b: 4, c: 3]

iex> Keyword.update!([a: 1], :b, &(&1 * 2))
** (KeyError) key :b not found in: [a: 1]
@spec values(t()) :: [value()]

Returns all values from the keyword list.

Values from duplicated keys will be kept in the final list of values.

Examples

iex> Keyword.values(a: 1, b: 2)
[1, 2]
iex> Keyword.values(a: 1, b: 2, a: 3)
[1, 2, 3]