DualMap (dual_map_ex v0.1.2)
A DualMap is simply a dual-entry map struct that allows you to reference pairs of data using both, a key or a value. In a DualMap you can look up a value from its key or a key from its value.
In simple terms we could say that a DualMap is a map where there is no difference between key and value, both can be either one or the other.
How does it work?
A DualMap actually stores 2 maps, a direct one with the key => value pairs, and a reverse one with the value => key pairs. At the same time it also stores metadata about the names (ids) of the datas (called master keys).
To create a new DualMap you must use the DualMap.new
function. You must pass to it a pair of names that will be the identifiers of the master keys.
DualMap.new({:hostname, :ip})
The order of the master keys is important. If you later want to make insertions into the DualMap and you use the DualMap.put_ordered
function the value pairs will assume that they are ordered as defined at the time of creating the DualMap with DualMap.new
.
Let's see some examples:
iex> dm = DualMap.new({:hostname, :ip})
[]
iex> DualMap.put_ordered(dm, [
{"ns3", "192.168.0.4"},
{"ns2", "192.168.0.3"},
{"ns1", "192.168.0.2"}
])
[
{"ns1", "192.168.0.2"},
{"ns2", "192.168.0.3"},
{"ns3", "192.168.0.4"}
]
iex> DualMap.delete(dm, :ip, "192.168.0.3")
[
{"ns1", "192.168.0.2"},
{"ns3", "192.168.0.4"}
]
Summary
Functions
Return de size of the DualMap counting the number of pairs.
Delete a pair of datas and returns the DualMap without that pair. The pair is found looking for key
in the the internal map indexed by master_key
.
Just the same as delete/3
but you can pass a list of keys to delete.
Checks if two DualMaps are equal.
Just as get/4
but do not accept default parameter. If the key exists, will return the tuple {:ok, value}
and if not :error
.
Work equals to fetch/3
but erroring out if key doesn't exists.
Returns the value asociated to key
taking the internal map indexed by master_key
. If key
does not exists in the map, default
or nil
is returned.
Return the complete internal map indexed by master_key
.
Checks if key
exists within DualMap.
Return a list with all the keys of the internal map indexed by master_key
.
Checks if the pair key_value
(tuple size 2) exists within DualMap either as key => value or as value => key.
Returns an empty DualMap struct. The order of the master keys are important for posterior operations with the struct.
Returns a DualMap struct initialized with the values indicated in the second argument. As the new/1
function, the order of the master keys are important for posterior operations with the struct.
Insert or replace one or more pairs of datas in a DualMap. If the third parameters is a list of tuples, every one is inserted/replaced in the DualMap secuentialy. With this function you need pass the a master_key to indicate which value of the tuple will be interpreted as key and which one as value.
Return a list with all the values of the internal map indexed by master_key
.
Types
Functions
@spec count(t()) :: pos_integer()
Return de size of the DualMap counting the number of pairs.
Delete a pair of datas and returns the DualMap without that pair. The pair is found looking for key
in the the internal map indexed by master_key
.
Examples
iex> dm = DualMap.new({:hostname, :ip}, [
{"ns3", "192.168.0.4"},
{"ns2", "192.168.0.3"},
{"ns1", "192.168.0.2"}
])
[
{"ns1", "192.168.0.2"},
{"ns2", "192.168.0.3"},
{"ns3", "192.168.0.4"}
]
iex> DualMap.delete(dm, :ip, "192.168.0.3")
[
{"ns1", "192.168.0.2"},
{"ns3", "192.168.0.4"}
]
Just the same as delete/3
but you can pass a list of keys to delete.
Examples
iex> dm = DualMap.new({:hostname, :ip}, [
{"ns3", "192.168.0.4"},
{"ns2", "192.168.0.3"},
{"ns1", "192.168.0.2"}
])
[
{"ns1", "192.168.0.2"},
{"ns2", "192.168.0.3"},
{"ns3", "192.168.0.4"}
]
iex> DualMap.drop(dm, :ip, ["192.168.0.3", "192.168.0.2"])
[{"ns3", "192.168.0.4"}]
Checks if two DualMaps are equal.
Two maps are considered to be equal if both internal maps contains the same keys and values.
Just as get/4
but do not accept default parameter. If the key exists, will return the tuple {:ok, value}
and if not :error
.
Examples
iex> dm = DualMap.new({:hostname, :ip}, [
{"ns3", "192.168.0.4"},
{"ns2", "192.168.0.3"},
{"ns1", "192.168.0.2"}
])
iex> DualMap.fetch(dm, :ip, "192.168.0.4")
{:ok, "ns3"}
iex> DualMap.fetch(dm, :ip, "192.168.0.6")
:error
Work equals to fetch/3
but erroring out if key doesn't exists.
Returns the value asociated to key
taking the internal map indexed by master_key
. If key
does not exists in the map, default
or nil
is returned.
Examples
iex> dm = DualMap.new({:hostname, :ip}, [
{"ns3", "192.168.0.4"},
{"ns2", "192.168.0.3"},
{"ns1", "192.168.0.2"}
])
[
{"ns1", "192.168.0.2"},
{"ns2", "192.168.0.3"},
{"ns3", "192.168.0.4"}
]
iex> DualMap.get(dm, :ip, "192.168.0.4")
"ns3"
Return the complete internal map indexed by master_key
.
Examples
iex> dm = DualMap.new({:hostname, :ip}, [
{"ns3", "192.168.0.4"},
{"ns2", "192.168.0.3"},
{"ns1", "192.168.0.2"}
])
[
{"ns1", "192.168.0.2"},
{"ns2", "192.168.0.3"},
{"ns3", "192.168.0.4"}
]
iex> DualMap.get_map(dm, :hostname)
%{
"ns1" => "192.168.0.2",
"ns2" => "192.168.0.3",
"ns3" => "192.168.0.4"
}
Checks if key
exists within DualMap.
Examples
iex> dm = DualMap.new({:hostname, :ip}, [
{"ns3", "192.168.0.4"},
{"ns2", "192.168.0.3"},
{"ns1", "192.168.0.2"}
])
[
{"ns1", "192.168.0.2"},
{"ns2", "192.168.0.3"},
{"ns3", "192.168.0.4"}
]
iex> DualMap.has?(dm, "192.168.0.4")
true
iex> DualMap.has?(dm, "ns2")
true
iex> DualMap.has?(dm, "ns5")
false
Return a list with all the keys of the internal map indexed by master_key
.
Examples
iex> dm = DualMap.new({:hostname, :ip}, [
{"ns3", "192.168.0.4"},
{"ns2", "192.168.0.3"},
{"ns1", "192.168.0.2"}
])
iex> DualMap.keys(dm, :hostname)
["ns1", "ns2", "ns3"]
Checks if the pair key_value
(tuple size 2) exists within DualMap either as key => value or as value => key.
Examples
iex> dm = DualMap.new({:hostname, :ip}, [
{"ns3", "192.168.0.4"},
{"ns2", "192.168.0.3"},
{"ns1", "192.168.0.2"}
])
[
{"ns1", "192.168.0.2"},
{"ns2", "192.168.0.3"},
{"ns3", "192.168.0.4"}
]
iex> DualMap.member?(dm, {"192.168.0.4", "ns3"})
true
iex> DualMap.member?(dm, {"ns3", "192.168.0.4"})
true
iex> DualMap.member?(dm, {"ns1", "192.168.0.4"})
false
Returns an empty DualMap struct. The order of the master keys are important for posterior operations with the struct.
Examples
iex> DualMap.new({:hostname, :ip})
[]
Returns a DualMap struct initialized with the values indicated in the second argument. As the new/1
function, the order of the master keys are important for posterior operations with the struct.
Examples
# Initializing with one pair of values
iex> DualMap.new({:hostname, :ip}, {"ns1", "192.168.0.2"})
[{"ns1", "192.168.0.2"}]
# Initializing with more than one pair of values
iex> DualMap.new({:hostname, :ip}, [
{"ns3", "192.168.0.4"},
{"ns2", "192.168.0.3"},
{"ns1", "192.168.0.2"}
])
[
{"ns1", "192.168.0.2"},
{"ns2", "192.168.0.3"},
{"ns3", "192.168.0.4"}
]
Insert or replace one or more pairs of datas in a DualMap. If the third parameters is a list of tuples, every one is inserted/replaced in the DualMap secuentialy. With this function you need pass the a master_key to indicate which value of the tuple will be interpreted as key and which one as value.
Examples
iex> dm = DualMap.new({:hostname, :ip})
[]
# Inserting/replacing many
iex> DualMap.put(dm, :ip, [
{"192.168.0.4", "ns3"},
{"192.168.0.3", "ns2"},
{"192.168.0.2", "ns1"}
])
[
{"ns1", "192.168.0.2"},
{"ns2", "192.168.0.3"},
{"ns3", "192.168.0.4"}
]
Or inserting just one
iex> DualMap.put(dm, :ip, {"192.168.0.4", "ns3"})
[{"ns3", "192.168.0.4"}]
This function is similar to put/3
but you does not need pass a master key because the function will assume that you are sending the keys and values in the same order as you defined when you created the DualMap with new/1
or new/2
.
Examples
iex> dm = DualMap.new({:hostname, :ip})
[]
iex> DualMap.put_ordered(dm, [
{"ns3", "192.168.0.4"},
{"ns2", "192.168.0.3"},
{"ns1", "192.168.0.2"}
])
[
{"ns1", "192.168.0.2"},
{"ns2", "192.168.0.3"},
{"ns3", "192.168.0.4"}
]
Return a list of the pairs {key, value}
taking the map indexed by the first master_key defined with new/1
or new/2
. This function is used by inspect
to print the DualMap.
If you also pass an option :pairs_inverted
, the list will have the pairs with key/value inverted because will take the internal map indexed by the second master_key defined with new/1
or new/2
.
Return a list with all the values of the internal map indexed by master_key
.
Examples
iex> dm = DualMap.new({:hostname, :ip}, [
{"ns3", "192.168.0.4"},
{"ns2", "192.168.0.3"},
{"ns1", "192.168.0.2"}
])
[
{"ns1", "192.168.0.2"},
{"ns2", "192.168.0.3"},
{"ns3", "192.168.0.4"}
]
iex> DualMap.values(dm, :hostname)
["192.168.0.2", "192.168.0.3", "192.168.0.4"]