Keyword
Keyword lists are lists of two-element tuples, where the first element of the tuple is an atom and the second element can be any value, used mostly 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 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.
The functions in Keyword
do not guarantee any property when it comes to ordering. However, since a keyword list is simply a list, all the operations defined in Enum
and List
can be applied too, especially when ordering is required.
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, then the square brackets around the keyword list can be omitted as well. 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}
Summary
Types
Functions
- delete(keywords, key)
Deletes the entries in the keyword list for a specific
key
.- delete_first(keywords, key)
Deletes the first entry in the keyword list for a specific
key
.- drop(keywords, keys)
Drops the given keys from the keyword list.
- equal?(left, right)
Checks if two keywords are equal.
- fetch(keywords, key)
Fetches the value for a specific
key
and returns it in a tuple.- fetch!(keywords, key)
Fetches the value for specific
key
.- get(keywords, key, default \\ nil)
Gets the value for a specific
key
.- get_and_update(keywords, key, fun)
Gets the value from
key
and updates it, all in one pass.- get_and_update!(keywords, key, fun)
Gets the value from
key
and updates it. Raises if there is nokey
.- get_lazy(keywords, key, fun)
Gets the value for a specific
key
.- get_values(keywords, key)
Gets all values for a specific
key
.- has_key?(keywords, key)
Returns whether a given
key
exists in the givenkeywords
.- keys(keywords)
Returns all keys from the keyword list.
- keyword?(term)
Returns
true
ifterm
is a keyword list; otherwise returnsfalse
.- merge(keywords1, keywords2)
Merges two keyword lists into one.
- merge(keywords1, keywords2, fun)
Merges two keyword lists into one.
- new()
Returns an empty keyword list, i.e. an empty list.
- new(pairs)
Creates a keyword list from an enumerable.
- new(pairs, transform)
Creates a keyword list from an enumerable via the transformation function.
- pop(keywords, key, default \\ nil)
Returns the first value for
key
and removes all associated entries in the keyword list.- pop!(keywords, key)
Returns the first value for
key
and removes all associated antries in the keyword list, raising ifkey
is not present.- pop_first(keywords, key, default \\ nil)
Returns and removes the first value associated with
key
in the keyword list.- pop_lazy(keywords, key, fun)
Lazily returns and removes all values associated with
key
in the keyword list.- pop_values(keywords, key)
Returns all values for
key
and removes all associated entries in the keyword list.- put(keywords, key, value)
Puts the given
value
underkey
.- put_new(keywords, key, value)
Puts the given
value
underkey
unless the entrykey
already exists.- put_new_lazy(keywords, key, fun)
Evaluates
fun
and puts the result underkey
in keyword list unlesskey
is already present.- replace!(keywords, key, value)
Alters the value stored under
key
tovalue
, but only if the entrykey
already exists inkeywords
.- split(keywords, keys)
Takes all entries corresponding to the given keys and extracts them into a separate keyword list.
- take(keywords, keys)
Takes all entries corresponding to the given keys and returns them in a new keyword list.
- to_list(keyword)
Returns the keyword list itself.
- update(keywords, key, initial, fun)
Updates the
key
inkeywords
with the given function.- update!(keywords, key, fun)
Updates the
key
with the given function.- values(keywords)
Returns all values from the keyword list.
Types
key()
Specs
key() :: atom()
t()
Specs
t() :: [{key(), value()}]
t(value)
Specs
t(value) :: [{key(), value}]
value()
Specs
value() :: any()
Functions
delete(keywords, key)
Specs
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]
delete_first(keywords, key)
Specs
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]
drop(keywords, keys)
Specs
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]
equal?(left, right)
Specs
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
fetch(keywords, key)
Specs
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
fetch!(keywords, key)
Specs
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]
get(keywords, key, default \\ nil)
Specs
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
get_and_update(keywords, key, fun)
Specs
get_and_update(t(), key(), (value() -> {get, value()} | :pop)) :: {get, t()} when get: term()
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 "get" 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 "get" 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]}
get_and_update!(keywords, key, fun)
Specs
get_and_update!(t(), key(), (value() -> {get, value()})) :: {get, t()} when get: term()
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 "get" 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 "get" 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, []}
get_lazy(keywords, key, fun)
Specs
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
get_values(keywords, key)
Specs
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]
has_key?(keywords, key)
Specs
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
keys(keywords)
Specs
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]
keyword?(term)
Specs
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
merge(keywords1, keywords2)
Specs
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]
merge(keywords1, keywords2, fun)
Specs
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]
new()
Specs
new() :: []
Returns an empty keyword list, i.e. an empty list.
Examples
iex> Keyword.new() []
new(pairs)
Specs
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]
new(pairs, transform)
Specs
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]
pop(keywords, key, default \\ nil)
Specs
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, []}
pop!(keywords, key)
Specs
pop!(t(), key()) :: {value(), t()}
Returns the first value for key
and removes all associated antries 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]
pop_first(keywords, key, default \\ nil)
Specs
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]}
pop_lazy(keywords, key, fun)
Specs
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]}
pop_values(keywords, key)
Specs
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], []}
put(keywords, key, value)
Specs
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]
put_new(keywords, key, value)
Specs
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]
put_new_lazy(keywords, key, fun)
Specs
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]
replace!(keywords, key, value)
Specs
replace!(t(), key(), value()) :: t()
Alters the value stored under key
to value
, but only if the entry 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]
split(keywords, keys)
Specs
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]}
take(keywords, keys)
Specs
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]
to_list(keyword)
Specs
to_list(t()) :: t()
Returns the keyword list itself.
Examples
iex> Keyword.to_list(a: 1) [a: 1]
update(keywords, key, initial, fun)
Specs
update(t(), key(), value(), (value() -> value())) :: t()
Updates the key
in keywords
with the given function.
If the key
does not exist, inserts the given initial
value.
If there are duplicated keys, they are all removed and only the first one is updated.
Examples
iex> Keyword.update([a: 1], :a, 13, &(&1 * 2)) [a: 2] iex> Keyword.update([a: 1, a: 2], :a, 13, &(&1 * 2)) [a: 2] iex> Keyword.update([a: 1], :b, 11, &(&1 * 2)) [a: 1, b: 11]
update!(keywords, key, fun)
Specs
update!(t(), key(), (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]
values(keywords)
Specs
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]
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.10.4/Keyword.html