A.OrdMap (Aja v0.4.0) View Source
A Map preserving key insertion order, with efficient lookups and updates.
Works just like regular maps, except that the insertion order is preserved:
iex> %{"one" => 1, "two" => 2, "three" => 3}
%{"one" => 1, "three" => 3, "two" => 2}
iex> A.OrdMap.new([{"one", 1}, {"two", 2}, {"three", 3}])
#A<ord(%{"one" => 1, "two" => 2, "three" => 3})>
There is an unavoidable overhead compared to natively implemented maps, so keep using regular maps when you do not care about the insertion order.
- provides efficient (logarithmic) access: it is not a simple list of tuples
- implements the
Access
behaviour,Enum
/Inspect
/Collectable
protocols - optionally implements the
Jason.Encoder
protocol ifJason
is installed
Examples
A.OrdMap
offers the same API as Map
:
iex> ord_map = A.OrdMap.new([b: "Bat", a: "Ant", c: "Cat"])
#A<ord(%{b: "Bat", a: "Ant", c: "Cat"})>
iex> A.OrdMap.get(ord_map, :c)
"Cat"
iex> A.OrdMap.fetch(ord_map, :a)
{:ok, "Ant"}
iex> A.OrdMap.put(ord_map, :d, "Dinosaur")
#A<ord(%{b: "Bat", a: "Ant", c: "Cat", d: "Dinosaur"})>
iex> A.OrdMap.put(ord_map, :b, "Buffalo")
#A<ord(%{b: "Buffalo", a: "Ant", c: "Cat"})>
iex> A.OrdMap.delete(ord_map, :b)
#A<ord(%{a: "Ant", c: "Cat"})>
iex> Enum.to_list(ord_map)
[b: "Bat", a: "Ant", c: "Cat"]
iex> [d: "Dinosaur", b: "Buffalo", e: "Eel"] |> Enum.into(ord_map)
#A<ord(%{b: "Buffalo", a: "Ant", c: "Cat", d: "Dinosaur", e: "Eel"})>
Tree-specific functions
Due to its sorted nature, A.OrdMap
also offers some extra methods not present in Map
, like:
first/1
andlast/1
to efficiently retrieve the first / last key-value pairpop_first/1
andpop_last/1
to efficiently pop the first / last key-value pairfoldl/3
andfoldr/3
to efficiently fold (reduce) from left-to-right or right-to-left
Examples:
iex> ord_map = A.OrdMap.new(b: "Bat", a: "Ant", c: "Cat")
iex> A.OrdMap.first(ord_map)
{:b, "Bat"}
iex> {:c, "Cat", updated} = A.OrdMap.pop_last(ord_map)
iex> updated
#A<ord(%{b: "Bat", a: "Ant"})>
iex> A.OrdMap.foldr(ord_map, [], fn _key, value, acc -> [value <> "man" | acc] end)
["Batman", "Antman", "Catman"]
Access behaviour
A.OrdMap
implements the Access
behaviour.
iex> ord_map = A.OrdMap.new([a: "Ant", b: "Bat", c: "Cat"])
iex> ord_map[:a]
"Ant"
iex> put_in(ord_map[:b], "Buffalo")
#A<ord(%{a: "Ant", b: "Buffalo", c: "Cat"})>
iex> put_in(ord_map[:d], "Dinosaur")
#A<ord(%{a: "Ant", b: "Bat", c: "Cat", d: "Dinosaur"})>
iex> {"Cat", updated} = pop_in(ord_map[:c]); updated
#A<ord(%{a: "Ant", b: "Bat"})>
Convenience ord/1
macro
The A.OrdMap
module can be used without any macro.
The A.ord/1
macro does however provide some syntactic sugar to make
it more convenient to work with ordered maps, namely:
- construct new ordered maps without the clutter of a entry list
- pattern match on key-values like regular maps
- update some existing keys
Examples:
iex> import A
iex> ord_map = ord(%{"一" => 1, "二" => 2, "三" => 3})
#A<ord(%{"一" => 1, "二" => 2, "三" => 3})>
iex> ord(%{"三" => three, "一" => one}) = ord_map
iex> {one, three}
{1, 3}
iex> ord(%{ord_map | "二" => "NI!"})
#A<ord(%{"一" => 1, "二" => "NI!", "三" => 3})>
Note: pattern-matching on keys doesn't care about the insertion order.
With Jason
iex> A.OrdMap.new([{"un", 1}, {"deux", 2}, {"trois", 3}]) |> Jason.encode!()
"{\"un\":1,\"deux\":2,\"trois\":3}"
It also preserves the insertion order. Comparing with a regular map:
iex> Map.new([{"un", 1}, {"deux", 2}, {"trois", 3}]) |> Jason.encode!()
"{\"deux\":2,\"trois\":3,\"un\":1}"
There is no way as of now to decode JSON using A.OrdMap
.
Limitations: equality
A.OrdMap
comparisons based on ==/2
, ===/2
or the pin operator ^
are UNRELIABLE.
In Elixir, pattern-matching and equality for structs work based on their internal representation. While this is a pragmatic design choice that simplifies the language, it means that we cannot rededine how they work for custom data structures.
Two ordered maps that are semantically equal (same key-value pairs in the same order) might be considered non-equal when comparing their internals, because there is not a unique way of representing one same map.
A.OrdMap.equal?/2
should be used instead:
iex> ord_map1 = A.OrdMap.new(a: "Ant", b: "Bat")
#A<ord(%{a: "Ant", b: "Bat"})>
iex> ord_map2 = A.OrdMap.new(c: "Cat", a: "Ant", b: "Bat") |> A.OrdMap.delete(:c)
#A<ord(%{a: "Ant", b: "Bat"})>
iex> ord_map1 == ord_map2
false
iex> A.OrdMap.equal?(ord_map1, ord_map2)
true
iex> match?(^ord_map1, ord_map2)
false
Pattern-matching and opaque type
An A.OrdMap
is represented internally using the %A.OrdMap{}
struct. This struct
can be used whenever there's a need to pattern match on something being an A.OrdMap
:
iex> match?(%A.OrdMap{}, A.OrdMap.new())
true
Note, however, than A.OrdMap
is an opaque type:
its struct internal fields must not be accessed directly.
As discussed in the previous section, ord/1
makes it
possible to pattern match on keys as well as checking the type.
Memory overhead
A.OrdMap
takes roughly more memory 2.5~3x than a regular map depending on the type of data:
iex> map_size = 1..100 |> Map.new(fn i -> {i, <<i>>} end) |> :erts_debug.size()
658
iex> ord_map_size = 1..100 |> A.OrdMap.new(fn i -> {i, <<i>>} end) |> :erts_debug.size()
1668
iex> div(100 * ord_map_size, map_size)
253
Difference with A.RBMap
Link to this section Summary
Functions
Deletes the entry in ord_map
for a specific key
.
Drops the given keys
from ord_map
.
Checks if two ordered maps are equal, meaning they have the same key-value pairs in the same order.
Fetches the value for a specific key
and returns it in a ok-entry.
If the key does not exist, returns :error.
Fetches the value for a specific key
in the given ord_map
,
erroring out if ord_map
doesn't contain key
.
Finds the fist {key, value}
pair in ord_map
.
Folds (reduces) the given ord_map
from the left with the function fun
.
Requires an accumulator acc
.
Folds (reduces) the given ord_map
from the right with the function fun
.
Requires an accumulator acc
.
Converts a struct
to an ordered map.
Gets the value for a specific key
in ord_map
.
Gets the value from key
and updates it, all in one pass.
Gets the value from key
and updates it, all in one pass.
Gets the value for a specific key
in ord_map
.
Returns whether the given key
exists in ord_map
.
Returns all keys from ord_map
.
Finds the last {key, value}
pair in ord_map
.
Merges two ordered maps into one.
Returns a new empty ordered map.
Creates an ordered map from an enumerable
.
Creates an ordered map from an enumerable
via the given transform
function.
Returns the value for key
and the updated ordered map without key
.
Returns the value for key
and the updated ordered map without key
.
Finds and pops the first {key, value}
pair in ord_map
.
Finds and pops the last {key, value}
pair in ord_map
.
Lazily returns and removes the value associated with key
in ord_map
.
Puts the given value
under key
in ord_map
.
Puts the given value
under key
unless the entry key
already exists in ord_map
.
Evaluates fun
and puts the result under key
in ord_map
unless key
is already present.
Puts a value under key
only if the key
already exists in ord_map
.
Puts a value under key
only if the key
already exists in ord_map
.
Returns the number of keys in ord_map
.
Returns a new ordered map with all the key-value pairs in ord_map
where the key
is in keys
.
Returns all values from ord_map
.
Puts a value under key
only if the key
already exists in ord_map
.
Puts a value under key
only if the key
already exists in ord_map
.
Returns all values from ord_map
.
Link to this section Types
Link to this section Functions
Specs
Deletes the entry in ord_map
for a specific key
.
If the key
does not exist, returns ord_map
unchanged.
Examples
iex> ord_map = A.OrdMap.new(a: "Ant", b: "Bat", c: "Cat")
iex> A.OrdMap.delete(ord_map, :b)
#A<ord(%{a: "Ant", c: "Cat"})>
iex> A.OrdMap.delete(ord_map, :z)
#A<ord(%{a: "Ant", b: "Bat", c: "Cat"})>
Specs
Drops the given keys
from ord_map
.
If keys
contains keys that are not in ord_map
, they're simply ignored.
Examples
iex> ord_map = A.OrdMap.new(a: "Ant", b: "Bat", c: "Cat")
iex> A.OrdMap.drop(ord_map, [:b, :d])
#A<ord(%{a: "Ant", c: "Cat"})>
Specs
Checks if two ordered maps are equal, meaning they have the same key-value pairs in the same order.
Examples
iex> A.OrdMap.equal?(A.OrdMap.new(a: 1, b: 2), A.OrdMap.new(a: 1, b: 2))
true
iex> A.OrdMap.equal?(A.OrdMap.new(a: 1, b: 2), A.OrdMap.new(b: 2, a: 1))
false
iex> A.OrdMap.equal?(A.OrdMap.new(a: 1, b: 2), A.OrdMap.new(a: 3, b: 2))
false
Specs
Fetches the value for a specific key
and returns it in a ok-entry.
If the key does not exist, returns :error.
Examples
iex> ord_map = A.OrdMap.new(a: "A", b: "B", c: "C")
iex> A.OrdMap.fetch(ord_map, :c)
{:ok, "C"}
iex> A.OrdMap.fetch(ord_map, :z)
:error
Specs
Fetches the value for a specific key
in the given ord_map
,
erroring out if ord_map
doesn't contain key
.
If ord_map
doesn't contain key
, a KeyError
exception is raised.
Examples
iex> ord_map = A.OrdMap.new(a: "A", b: "B", c: "C")
iex> A.OrdMap.fetch!(ord_map, :c)
"C"
iex> A.OrdMap.fetch!(ord_map, :z)
** (KeyError) key :z not found in: #A<ord(%{a: "A", b: "B", c: "C"})>
Specs
Finds the fist {key, value}
pair in ord_map
.
Returns a {key, value}
entry if ord_map
is non-empty, or nil
else.
Examples
iex> A.OrdMap.new([b: "B", d: "D", a: "A", c: "C"]) |> A.OrdMap.first()
{:b, "B"}
iex> A.OrdMap.new([]) |> A.OrdMap.first()
nil
iex> A.OrdMap.new([]) |> A.OrdMap.first(:error)
:error
Folds (reduces) the given ord_map
from the left with the function fun
.
Requires an accumulator acc
.
Examples
iex> ord_map = A.OrdMap.new([b: "Bat", c: "Cat", a: "Ant"])
iex> A.OrdMap.foldl(ord_map, "", fn _key, value, acc -> value <> acc end)
"AntCatBat"
iex> A.OrdMap.foldl(ord_map, [], fn key, value, acc -> [{key, value <> "man"} | acc] end)
[a: "Antman", c: "Catman", b: "Batman"]
Folds (reduces) the given ord_map
from the right with the function fun
.
Requires an accumulator acc
.
Unlike linked lists, this is as efficient as foldl/3
. This can typically save a call
to Enum.reverse/1
on the result when building a list.
Examples
iex> ord_map = A.OrdMap.new([b: "Bat", c: "Cat", a: "Ant"])
iex> A.OrdMap.foldr(ord_map, "", fn _key, value, acc -> value <> acc end)
"BatCatAnt"
iex> A.OrdMap.foldr(ord_map, [], fn key, value, acc -> [{key, value <> "man"} | acc] end)
[b: "Batman", c: "Catman", a: "Antman"]
Specs
Converts a struct
to an ordered 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, :age]
end
A.OrdMap.from_struct(User)
#A<ord(%{age: nil, name: nil})>
A.OrdMap.from_struct(%User{name: "john", age: 44})
#A<ord(%{age: 44, name: "john"})>
Specs
Gets the value for a specific key
in ord_map
.
If key
is present in ord_map
then its value value
is
returned. Otherwise, default
is returned.
If default
is not provided, nil
is used.
Examples
iex> ord_map = A.OrdMap.new(a: "Ant", b: "Bat", c: "Cat")
iex> A.OrdMap.get(ord_map, :a)
"Ant"
iex> A.OrdMap.get(ord_map, :z)
nil
iex> A.OrdMap.get(ord_map, :z, "Zebra")
"Zebra"
Specs
get_and_update(t(k, v), k, (v -> {returned, v} | :pop)) :: {returned, t(k, v)} when k: key(), v: value(), returned: term()
Gets the value from key
and updates it, all in one pass.
Mirrors Map.get_and_update/3
, see its documentation.
Examples
iex> ord_map = A.OrdMap.new(a: "Ant", b: "Bat", c: "Cat")
iex> {"bat", updated} = A.OrdMap.get_and_update(ord_map, :b, fn current_value ->
...> {current_value && String.downcase(current_value), "Buffalo"}
...> end)
iex> updated
#A<ord(%{a: "Ant", b: "Buffalo", c: "Cat"})>
iex> {nil, updated} = A.OrdMap.get_and_update(ord_map, :z, fn current_value ->
...> {current_value && String.downcase(current_value), "Zebra"}
...> end)
iex> updated
#A<ord(%{a: "Ant", b: "Bat", c: "Cat", z: "Zebra"})>
iex> {"Bat", updated} = A.OrdMap.get_and_update(ord_map, :b, fn _ -> :pop end)
iex> updated
#A<ord(%{a: "Ant", c: "Cat"})>
iex> {nil, updated} = A.OrdMap.get_and_update(ord_map, :z, fn _ -> :pop end)
iex> updated
#A<ord(%{a: "Ant", b: "Bat", c: "Cat"})>
Specs
get_and_update!(t(k, v), k, (v -> {returned, v} | :pop)) :: {returned, t(k, v)} when k: key(), v: value(), returned: term()
Gets the value from key
and updates it, all in one pass.
Mirrors Map.get_and_update!/3
, see its documentation.
Examples
iex> ord_map = A.OrdMap.new(a: "Ant", b: "Bat", c: "Cat")
iex> {"bat", updated} = A.OrdMap.get_and_update!(ord_map, :b, fn current_value ->
...> {current_value && String.downcase(current_value), "Buffalo"}
...> end)
iex> updated
#A<ord(%{a: "Ant", b: "Buffalo", c: "Cat"})>
iex> A.OrdMap.get_and_update!(ord_map, :z, fn current_value ->
...> {current_value && String.downcase(current_value), "Zebra"}
...> end)
** (KeyError) key :z not found in: #A<ord(%{a: "Ant", b: "Bat", c: "Cat"})>
Specs
Gets the value for a specific key
in ord_map
.
If key
is present in ord_map
then its value 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> ord_map = A.OrdMap.new(a: "Ant", b: "Bat", c: "Cat")
iex> expensive_fun = fn -> "Zebra" end
iex> A.OrdMap.get_lazy(ord_map, :a, expensive_fun)
"Ant"
iex> A.OrdMap.get_lazy(ord_map, :z, expensive_fun)
"Zebra"
Specs
Returns whether the given key
exists in ord_map
.
Examples
iex> ord_map = A.OrdMap.new(a: "Ant", b: "Bat", c: "Cat")
iex> A.OrdMap.has_key?(ord_map, :a)
true
iex> A.OrdMap.has_key?(ord_map, :d)
false
Specs
Returns all keys from ord_map
.
Examples
iex> ord_map = A.OrdMap.new(b: "Bat", c: "Cat", a: "Ant")
iex> A.OrdMap.keys(ord_map)
[:b, :c, :a]
Specs
Finds the last {key, value}
pair in ord_map
.
Returns a {key, value}
entry if ord_map
is non-empty, or nil
else.
Can be accessed efficiently due to the underlying tree.
Examples
iex> A.OrdMap.new([b: "B", d: "D", a: "A", c: "C"]) |> A.OrdMap.last()
{:c, "C"}
iex> A.OrdMap.new([]) |> A.OrdMap.last()
nil
iex> A.OrdMap.new([]) |> A.OrdMap.last(:error)
:error
Specs
Merges two ordered maps into one.
All keys in ord_map2
will be added to ord_map1
, overriding any existing one
(i.e., the keys in ord_map2
"have precedence" over the ones in ord_map1
).
Examples
iex> A.OrdMap.merge(A.OrdMap.new(%{a: 1, b: 2}), A.OrdMap.new(%{a: 3, d: 4}))
#A<ord(%{a: 3, b: 2, d: 4})>
Specs
new() :: t()
Returns a new empty ordered map.
Examples
iex> A.OrdMap.new()
#A<ord(%{})>
Specs
new(Enumerable.t()) :: t(key(), value())
Creates an ordered map from an enumerable
.
Preserves the original order of keys. Duplicated keys are removed; the latest one prevails.
Examples
iex> A.OrdMap.new(b: "Bat", a: "Ant", c: "Cat")
#A<ord(%{b: "Bat", a: "Ant", c: "Cat"})>
iex> A.OrdMap.new(b: "Bat", a: "Ant", b: "Buffalo", a: "Antelope")
#A<ord(%{b: "Buffalo", a: "Antelope"})>
Specs
new(Enumerable.t(), (term() -> {k, v})) :: t(k, v) when k: key(), v: value()
Creates an ordered map from an enumerable
via the given transform
function.
Preserves the original order of keys. Duplicated keys are removed; the latest one prevails.
Examples
iex> A.OrdMap.new([:a, :b], fn x -> {x, x} end)
#A<ord(%{a: :a, b: :b})>
Specs
Returns the value for key
and the updated ordered map without key
.
If key
is present in the ordered map with a value value
,
{value, new_ord_map}
is returned.
If key
is not present in the ordered map, {default, ord_map}
is returned.
Examples
iex> ord_map = A.OrdMap.new(a: "Ant", b: "Bat", c: "Cat")
iex> {"Bat", updated} = A.OrdMap.pop(ord_map, :b)
iex> updated
#A<ord(%{a: "Ant", c: "Cat"})>
iex> {nil, updated} = A.OrdMap.pop(ord_map, :z)
iex> updated
#A<ord(%{a: "Ant", b: "Bat", c: "Cat"})>
iex> {"Z", updated} = A.OrdMap.pop(ord_map, :z, "Z")
iex> updated
#A<ord(%{a: "Ant", b: "Bat", c: "Cat"})>
Specs
Returns the value for key
and the updated ordered map without key
.
Behaves the same as pop/3
but raises if key
is not present in ord_map
.
Examples
iex> ord_map = A.OrdMap.new(a: "Ant", b: "Bat", c: "Cat")
iex> {"Bat", updated} = A.OrdMap.pop!(ord_map, :b)
iex> updated
#A<ord(%{a: "Ant", c: "Cat"})>
iex> A.OrdMap.pop!(ord_map, :z)
** (KeyError) key :z not found in: #A<ord(%{a: "Ant", b: "Bat", c: "Cat"})>
Specs
Finds and pops the first {key, value}
pair in ord_map
.
Returns a {key, value, new_tree}
entry for non-empty maps, nil
for empty maps
Examples
iex> ord_map = A.OrdMap.new([b: "B", d: "D", a: "A", c: "C"])
#A<ord(%{b: "B", d: "D", a: "A", c: "C"})>
iex> {:b, "B", updated} = A.OrdMap.pop_first(ord_map)
iex> updated
#A<ord(%{d: "D", a: "A", c: "C"})>
iex> A.OrdMap.new() |> A.OrdMap.pop_first()
nil
Specs
Finds and pops the last {key, value}
pair in ord_map
.
Returns a {key, value, new_tree}
entry for non-empty maps, nil
for empty maps
Examples
iex> ord_map = A.OrdMap.new([b: "B", d: "D", a: "A", c: "C"])
#A<ord(%{b: "B", d: "D", a: "A", c: "C"})>
iex> {:c, "C", updated} = A.OrdMap.pop_last(ord_map)
iex> updated
#A<ord(%{b: "B", d: "D", a: "A"})>
iex> A.OrdMap.new() |> A.OrdMap.pop_last()
nil
Specs
Lazily returns and removes the value associated with key
in ord_map
.
If key
is present in ord_map
, it returns {value, new_map}
where value
is the value of
the key and new_map
is the result of removing key
from ord_map
. If key
is not present in ord_map
, {fun_result, ord_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> ord_map = A.OrdMap.new(b: "Bat", a: "Ant", c: "Cat")
iex> expensive_fun = fn -> "Zebra" end
iex> {"Ant", updated} = A.OrdMap.pop_lazy(ord_map, :a, expensive_fun)
iex> updated
#A<ord(%{b: "Bat", c: "Cat"})>
iex> {"Zebra", not_updated} = A.OrdMap.pop_lazy(ord_map, :z, expensive_fun)
iex> not_updated
#A<ord(%{b: "Bat", a: "Ant", c: "Cat"})>
Specs
Puts the given value
under key
in ord_map
.
If the key
does exist, it overwrites the existing value without
changing its current location.
Examples
iex> ord_map = A.OrdMap.new(a: "Ant", b: "Bat", c: "Cat")
iex> A.OrdMap.put(ord_map, :b, "Buffalo")
#A<ord(%{a: "Ant", b: "Buffalo", c: "Cat"})>
iex> A.OrdMap.put(ord_map, :d, "Dinosaur")
#A<ord(%{a: "Ant", b: "Bat", c: "Cat", d: "Dinosaur"})>
Specs
Puts the given value
under key
unless the entry key
already exists in ord_map
.
Examples
iex> ord_map = A.OrdMap.new(b: "Bat", c: "Cat")
iex> A.OrdMap.put_new(ord_map, :a, "Ant")
#A<ord(%{b: "Bat", c: "Cat", a: "Ant"})>
iex> A.OrdMap.put_new(ord_map, :b, "Buffalo")
#A<ord(%{b: "Bat", c: "Cat"})>
Specs
Evaluates fun
and puts the result under key
in ord_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, as for example, when the value is expensive to
calculate or generally difficult to setup and teardown again.
Examples
iex> ord_map = A.OrdMap.new(b: "Bat", c: "Cat")
iex> expensive_fun = fn -> "Ant" end
iex> A.OrdMap.put_new_lazy(ord_map, :a, expensive_fun)
#A<ord(%{b: "Bat", c: "Cat", a: "Ant"})>
iex> A.OrdMap.put_new_lazy(ord_map, :b, expensive_fun)
#A<ord(%{b: "Bat", c: "Cat"})>
Specs
Puts a value under key
only if the key
already exists in ord_map
.
Examples
iex> ord_map = A.OrdMap.new(a: "Ant", b: "Bat", c: "Cat")
iex> A.OrdMap.replace(ord_map, :b, "Buffalo")
#A<ord(%{a: "Ant", b: "Buffalo", c: "Cat"})>
iex> A.OrdMap.replace(ord_map, :d, "Dinosaur")
#A<ord(%{a: "Ant", b: "Bat", c: "Cat"})>
Specs
Puts a value under key
only if the key
already exists in ord_map
.
If key
is not present in ord_map
, a KeyError
exception is raised.
Examples
iex> ord_map = A.OrdMap.new(a: "Ant", b: "Bat", c: "Cat")
iex> A.OrdMap.replace!(ord_map, :b, "Buffalo")
#A<ord(%{a: "Ant", b: "Buffalo", c: "Cat"})>
iex> A.OrdMap.replace!(ord_map, :d, "Dinosaur")
** (KeyError) key :d not found in: #A<ord(%{a: "Ant", b: "Bat", c: "Cat"})>
Specs
size(t()) :: non_neg_integer()
Returns the number of keys in ord_map
.
Examples
iex> ord_map = A.OrdMap.new(a: "Ant", b: "Bat", c: "Cat")
iex> A.OrdMap.size(ord_map)
3
iex> A.OrdMap.size(A.OrdMap.new())
0
Returns a new ordered map with all the key-value pairs in ord_map
where the key
is in keys
.
If keys
contains keys that are not in ord_map
, they're simply ignored.
Respects the order of the keys
list.
Examples
iex> ord_map = A.OrdMap.new(a: "Ant", b: "Bat", c: "Cat")
iex> A.OrdMap.take(ord_map, [:c, :e, :a])
#A<ord(%{c: "Cat", a: "Ant"})>
Specs
Returns all values from ord_map
.
Examples
iex> ord_map = A.OrdMap.new(b: "Bat", c: "Cat", a: "Ant")
iex> A.OrdMap.to_list(ord_map)
[b: "Bat", c: "Cat", a: "Ant"]
Specs
Puts a value under key
only if the key
already exists in ord_map
.
Examples
iex> ord_map = A.OrdMap.new(a: "Ant", b: "Bat", c: "Cat")
iex> A.OrdMap.update(ord_map, :b, "N/A", &String.upcase/1)
#A<ord(%{a: "Ant", b: "BAT", c: "Cat"})>
iex> A.OrdMap.update(ord_map, :z, "N/A", &String.upcase/1)
#A<ord(%{a: "Ant", b: "Bat", c: "Cat", z: "N/A"})>
Specs
Puts a value under key
only if the key
already exists in ord_map
.
If key
is not present in ord_map
, a KeyError
exception is raised.
Examples
iex> ord_map = A.OrdMap.new(a: "Ant", b: "Bat", c: "Cat")
iex> A.OrdMap.update!(ord_map, :b, &String.upcase/1)
#A<ord(%{a: "Ant", b: "BAT", c: "Cat"})>
iex> A.OrdMap.update!(ord_map, :d, &String.upcase/1)
** (KeyError) key :d not found in: #A<ord(%{a: "Ant", b: "Bat", c: "Cat"})>
Specs
Returns all values from ord_map
.
Examples
iex> ord_map = A.OrdMap.new(b: "Bat", c: "Cat", a: "Ant")
iex> A.OrdMap.values(ord_map)
["Bat", "Cat", "Ant"]