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.

Source

Summary

delete(dict, key)

Removes the entry stored under the given key from dict. If dict does not contain key, returns the dictionary unchanged

drop(dict, keys)

Returns a new dict where the given keys are removed from dict. Any non-member keys are ignored

empty(dict)

Returns an empty dict of the same type as dict

equal?(dict1, dict2)

Check if two dicts are equal using ===

fetch!(dict, key)

Returns the value associated with key in dict. If dict does not contain key, it raises KeyError

fetch(dict, key)

Returns { :ok, value } associated with key in dict. If dict does not contain key, returns :error

get(dict, key, default \\ nil)

Returns the value associated with key in dict. If dict does not contain key, returns default (or nil if not provided)

has_key?(dict, key)

Returns whether the given key exists in the given dict

keys(dict)

Returns a list of all keys in dict. The keys are not guaranteed to be in any order

merge(dict1, dict2, fun \\ fn _k, _v1, v2 -> v2 end)

Merges the dict b into dict a

pop(dict, key, default \\ nil)

Returns the value associated with key in dict as well as the dict without key

put(dict, key, val)

Stores the given value under key in dict. If dict already has key, the stored value is replaced by the new one

put_new(dict, key, val)

Puts the given value under key in dict unless key already exists

size(dict)

Returns the number of elements in dict

split(dict, keys)

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

take(dict, keys)

Returns a new dict where only the keys in keys from dict are included

to_list(dict)

Returns a list of key-value pairs stored in dict. No particular order is enforced

update!(dict, key, fun)

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

update(dict, key, initial, fun)

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

values(dict)

Returns a list of all values in dict. The values are not guaranteed to be in any order

Types

key :: any

value :: any

t :: tuple | []

Functions

delete(dict, key)

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
Source
drop(dict, keys)

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]
Source
empty(dict)

Specs:

  • empty(t) :: t

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)
[]
Source
equal?(dict1, dict2)

Specs:

  • equal?(t, t) :: boolean

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
Source
fetch(dict, key)

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
Source
fetch!(dict, key)

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
Source
get(dict, key, default \\ nil)

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
Source
has_key?(dict, key)

Specs:

  • has_key?(t, key) :: boolean

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
Source
keys(dict)

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]
Source
merge(dict1, dict2, fun \\ fn _k, _v1, v2 -> v2 end)

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]
Source
pop(dict, key, default \\ nil)

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]}
Source
put(dict, key, val)

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
Source
put_new(dict, key, val)

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
Source
size(dict)

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
Source
split(dict, keys)

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], [] }
Source
take(dict, keys)

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)
[]
Source
to_list(dict)

Specs:

  • to_list(t) :: []

Returns a list of key-value pairs stored in dict. No particular order is enforced.

Source
update(dict, key, initial, fun)

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
Source
update!(dict, key, fun)

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
Source
values(dict)

Specs:

Returns a list of all values in dict. The values are not guaranteed to be in any order.

Examples

iex> d = dict_impl.new([a: 1, b: 2])
...> Enum.sort(Dict.values(d))
[1,2]
Source

Callbacks

delete(t, key)

Specs:

Source
drop(t, t)

Specs:

Source
empty(t)

Specs:

  • empty(t) :: t
Source
equal?(t, t)

Specs:

  • equal?(t, t) :: boolean
Source
fetch(t, key)

Specs:

Source
fetch!(t, key)

Specs:

Source
get(t, key)

Specs:

Source
get(t, key, value)

Specs:

Source
has_key?(t, key)

Specs:

  • has_key?(t, key) :: boolean
Source
keys(t)

Specs:

Source
merge(t, t)

Specs:

  • merge(t, t) :: t
Source
merge(t, t, list3)

Specs:

Source
new()

Specs:

  • new :: t
Source
new(t)

Specs:

Source
new(t, list2)

Specs:

Source
pop(t, key)

Specs:

Source
pop(t, key, value)

Specs:

Source
put(t, key, value)

Specs:

Source
put_new(t, key, value)

Specs:

Source
reduce(t, acc, reducer)

Specs:

Source
size(t)

Specs:

  • size(t) :: non_neg_integer
Source
split(t, t)

Specs:

Source
take(t, t)

Specs:

Source
to_list(t)

Specs:

  • to_list(t) :: []
Source
update(t, key, value, list4)

Specs:

Source
update!(t, key, list3)

Specs:

Source
values(t)

Specs:

Source