Dict behaviour
This module specifies the Dict API expected to be implemented by different dictionaries. It also provides functions that redirect to the underlying Dict, allowing a developer to work with different Dict implementations using one API.
To create a new dict, use the new functions defined
by each dict type:
HashDict.new #=> creates an empty HashDict
In the examples below, dict_impl means a specific
Dict implementation, for example HashDict or ListDict.
Protocols
Besides implementing the functions in this module, all
dictionaries are required to implement the Access
protocol:
iex> dict = dict_impl.new
...> dict = Dict.put(dict, :hello, :world)
...> dict[:hello]
:world
And the Enumerable protocol, allowing one to write:
Enum.each(dict, fn ({ k, v }) ->
IO.puts "#{k}: #{v}"
end)
Match
Dictionaries are required to implement all operations
using the match (===) operator.
Summary
| delete(dict, key) | Removes the entry stored under the given |
| drop(dict, keys) | Returns a new dict where the given |
| empty(dict) | Returns an empty dict of the same type as |
| equal?(dict1, dict2) | Check if two dicts are equal using |
| fetch!(dict, key) | Returns the value associated with |
| fetch(dict, key) | Returns |
| get(dict, key, default \\ nil) | Returns the value associated with |
| has_key?(dict, key) | Returns whether the given |
| keys(dict) | Returns a list of all keys in |
| merge(dict1, dict2, fun \\ fn _k, _v1, v2 -> v2 end) | Merges the dict |
| pop(dict, key, default \\ nil) | Returns the value associated with |
| put(dict, key, val) | Stores the given |
| put_new(dict, key, val) | Puts the given |
| size(dict) | Returns the number of elements in |
| split(dict, keys) | Returns a tuple of two dicts, where the first dict contains only
entries from |
| take(dict, keys) | Returns a new dict where only the keys in |
| to_list(dict) | Returns a list of key-value pairs stored in |
| update!(dict, key, fun) | Update a value in |
| update(dict, key, initial, fun) | Update a value in |
| values(dict) | Returns a list of all values in |
Functions
Specs:
Removes the entry stored under the given key from dict.
If dict does not contain key, returns the dictionary unchanged.
Examples
iex> d = dict_impl.new([a: 1, b: 2])
...> d = Dict.delete(d, :a)
...> Dict.get(d, :a)
nil
iex> d = dict_impl.new([b: 2])
...> Dict.delete(d, :a) == d
true
Specs:
Returns a new dict where the given keys are removed from dict.
Any non-member keys are ignored.
Examples
iex> d = dict_impl.new([a: 1, b: 2])
...> d = Dict.drop(d, [:a, :c, :d])
...> Dict.to_list(d)
[b: 2]
iex> d = dict_impl.new([a: 1, b: 2])
...> d = Dict.drop(d, [:c, :d])
...> Dict.to_list(d) |> Enum.sort
[a: 1, b: 2]
Specs:
Returns an empty dict of the same type as dict.
Examples
iex> d = dict_impl.new([a: 1, b: 2])
...> e = Dict.empty(d)
...> Dict.to_list(e)
[]
Specs:
Check if two dicts are equal using ===.
Notice this function is polymorphic as it compares dicts of any
type. Each dict implementation also provides an equal? function,
but they can only compare dicts of the same type.
Examples
iex> a = dict_impl.new(a: 2, b: 3, f: 5, c: 123)
...> b = [a: 2, b: 3, f: 5, c: 123]
...> Dict.equal?(a, b)
true
iex> a = dict_impl.new(a: 2, b: 3, f: 5, c: 123)
...> b = []
...> Dict.equal?(a, b)
false
Specs:
Returns { :ok, value } associated with key in dict.
If dict does not contain key, returns :error.
Examples
iex> d = dict_impl.new([a: 1])
iex> Dict.fetch(d, :a)
{ :ok, 1 }
iex> Dict.fetch(d, :b)
:error
Specs:
Returns the value associated with key in dict. If dict does not
contain key, it raises KeyError.
Examples
iex> d = dict_impl.new([a: 1])
iex> Dict.fetch!(d, :a)
1
iex> Dict.fetch!(d, :b)
** (KeyError) key not found: :b
Specs:
Returns the value associated with key in dict. If dict does not
contain key, returns default (or nil if not provided).
Examples
iex> d = dict_impl.new([a: 1])
iex> Dict.get(d, :a)
1
iex> Dict.get(d, :b)
nil
iex> Dict.get(d, :b, 3)
3
Specs:
Returns whether the given key exists in the given dict.
Examples
iex> d = dict_impl.new([a: 1])
iex> Dict.has_key?(d, :a)
true
iex> Dict.has_key?(d, :b)
false
Specs:
Returns a list of all keys in dict.
The keys are not guaranteed to be in any order.
Examples
iex> d = dict_impl.new([a: 1, b: 2])
...> Enum.sort(Dict.keys(d))
[:a,:b]
Specs:
Merges the dict b into dict a.
If one of the dict b entries already exists in the dict,
the functions in entries in b have higher precedence unless a
function is given to resolve conflicts.
Notice this function is polymorphic as it merges dicts of any
type. Each dict implementation also provides a merge function,
but they can only merge dicts of the same type.
Examples
iex> d1 = dict_impl.new([a: 1, b: 2])
...> d2 = dict_impl.new([a: 3, d: 4])
...> d = Dict.merge(d1, d2)
...> [a: Dict.get(d, :a), b: Dict.get(d, :b), d: Dict.get(d, :d)]
[a: 3, b: 2, d: 4]
iex> d1 = dict_impl.new([a: 1, b: 2])
...> d2 = dict_impl.new([a: 3, d: 4])
...> d = Dict.merge(d1, d2, fn(_k, v1, v2) ->
...> v1 + v2
...> end)
...> [a: Dict.get(d, :a), b: Dict.get(d, :b), d: Dict.get(d, :d)]
[a: 4, b: 2, d: 4]
Specs:
Returns the value associated with key in dict as
well as the dict without key.
Examples
iex> dict = dict_impl.new [a: 1]
...> {v, d} = Dict.pop dict, :a
...> {v, Enum.sort(d)}
{1,[]}
iex> dict = dict_impl.new [a: 1]
...> {v, d} = Dict.pop dict, :b
...> {v, Enum.sort(d)}
{nil,[a: 1]}
iex> dict = dict_impl.new [a: 1]
...> {v, d} = Dict.pop dict, :b, 3
...> {v, Enum.sort(d)}
{3,[a: 1]}
Specs:
Stores the given value under key in dict.
If dict already has key, the stored value is replaced by the new one.
Examples
iex> d = dict_impl.new([a: 1, b: 2])
...> d = Dict.put(d, :a, 3)
...> Dict.get(d, :a)
3
Specs:
Puts the given value under key in dict unless key already exists.
Examples
iex> d = dict_impl.new([a: 1, b: 2])
...> d = Dict.put_new(d, :a, 3)
...> Dict.get(d, :a)
1
Specs:
- size(t) :: non_neg_integer
Returns the number of elements in dict.
Examples
iex> d = dict_impl.new([a: 1, b: 2])
...> Dict.size(d)
2
Specs:
Returns a tuple of two dicts, where the first dict contains only
entries from dict with keys in keys, and the second dict
contains only entries from dict with keys not in keys
Any non-member keys are ignored.
Examples
iex> d = dict_impl.new([a: 1, b: 2, c: 3, d: 4])
...> { d1, d2 } = Dict.split(d, [:a, :c, :e])
...> { Dict.to_list(d1) |> Enum.sort, Dict.to_list(d2) |> Enum.sort }
{ [a: 1, c: 3], [b: 2, d: 4] }
iex> d = dict_impl.new([])
...> { d1, d2 } = Dict.split(d, [:a, :c])
...> { Dict.to_list(d1), Dict.to_list(d2) }
{ [], [] }
iex> d = dict_impl.new([a: 1, b: 2])
...> { d1, d2 } = Dict.split(d, [:a, :b, :c])
...> { Dict.to_list(d1) |> Enum.sort, Dict.to_list(d2) }
{ [a: 1, b: 2], [] }
Specs:
Returns a new dict where only the keys in keys from dict are included.
Any non-member keys are ignored.
Examples
iex> d = dict_impl.new([a: 1, b: 2])
...>
...> d = Dict.take(d, [:a, :c, :d])
...> Dict.to_list(d)
[a: 1]
...>
...> d = Dict.take(d, [:c, :d])
...> Dict.to_list(d)
[]
Specs:
- to_list(t) :: []
Returns a list of key-value pairs stored in dict.
No particular order is enforced.
Specs:
Update a value in dict by calling fun on the value to get a new value. If
key is not present in dict then initial will be stored as the first
value.
Examples
iex> d = dict_impl.new([a: 1, b: 2])
...> d = Dict.update(d, :c, 3, fn(val) -> -val end)
...> Dict.get(d, :c)
3
Specs:
Update a value in dict by calling fun on the value to get a new
value. An exception is generated if key is not present in the dict.
Examples
iex> d = dict_impl.new([a: 1, b: 2])
...> d = Dict.update!(d, :a, fn(val) -> -val end)
...> Dict.get(d, :a)
-1
Callbacks
Specs:
SourceSpecs:
Source