A dictionary that maintains a mapping from the values back to keys, allowing for modelling many-to-one relationships.
Example usage:
manyToOne : BiDict String Int
manyToOne =
BiDict.empty
|> BiDict.insert "A" 1
|> BiDict.insert "B" 2
|> BiDict.insert "C" 1
|> BiDict.insert "D" 4
BiDict.getReverse 1 manyToOne
--> Set.fromList ["A", "C"]
This module in particular uses assoc-list
and assoc-set
under the hood to get rid of the comparable
constraint on keys that's usually
associated with Dicts and Sets.
The underlying data structure. Think about it as
type alias BiDict a b =
{ forward : Dict a b -- just a normal Dict!
, reverse : Dict b (Set a) -- the reverse mappings!
}
toDict : BiDict a b -> AssocList.Dict a b
Convert BiDict into a Dict. (Throw away the reverse mapping.)
fromDict : AssocList.Dict a b -> BiDict a b
Convert Dict into a BiDict. (Compute the reverse mapping.)
getReverse : b -> BiDict a b -> AssocSet.Set a
Get the keys associated with a value. If the value is not found, return an empty set.
uniqueValues : BiDict a b -> List b
Get a list of unique values in the dictionary.
uniqueValuesCount : BiDict a b -> Basics.Int
Get a count of unique values in the dictionary.
toReverseList : BiDict a b -> List ( b, AssocSet.Set a )
Convert a dictionary into a reverse association list of value-keys pairs.
empty : BiDict a b
Create an empty dictionary.
singleton : a -> b -> BiDict a b
Create a dictionary with one key-value pair.
insert : a -> b -> BiDict a b -> BiDict a b
Insert a key-value pair into a dictionary. Replaces value when there is a collision.
update : a -> (Maybe b -> Maybe b) -> BiDict a b -> BiDict a b
Update the value of a dictionary for a specific key with a given function.
remove : a -> BiDict a b -> BiDict a b
Remove a key-value pair from a dictionary. If the key is not found, no changes are made.
isEmpty : BiDict a b -> Basics.Bool
Determine if a dictionary is empty.
isEmpty empty == True
member : a -> BiDict a b -> Basics.Bool
Determine if a key is in a dictionary.
get : a -> BiDict a b -> Maybe b
Get the value associated with a key. If the key is not found, return
Nothing
. This is useful when you are not sure if a key will be in the
dictionary.
animals = fromList [ ("Tom", Cat), ("Jerry", Mouse) ]
get "Tom" animals == Just Cat
get "Jerry" animals == Just Mouse
get "Spike" animals == Nothing
size : BiDict a b -> Basics.Int
Determine the number of key-value pairs in the dictionary.
keys : BiDict a b -> List a
Get all of the keys in a dictionary, sorted from lowest to highest.
keys (fromList [ ( 0, "Alice" ), ( 1, "Bob" ) ]) == [ 0, 1 ]
values : BiDict a b -> List b
Get all of the values in a dictionary, in the order of their keys.
values (fromList [ ( 0, "Alice" ), ( 1, "Bob" ) ]) == [ "Alice", "Bob" ]
toList : BiDict a b -> List ( a, b )
Convert a dictionary into an association list of key-value pairs, sorted by keys.
fromList : List ( a, b ) -> BiDict a b
Convert an association list into a dictionary.
map : (a -> b1 -> b2) -> BiDict a b1 -> BiDict a b2
Apply a function to all values in a dictionary.
foldl : (a -> b -> acc -> acc) -> acc -> BiDict a b -> acc
Fold over the key-value pairs in a dictionary from lowest key to highest key.
getAges users =
Dict.foldl addAge [] users
addAge _ user ages =
user.age :: ages
-- getAges users == [33,19,28]
foldr : (a -> b -> acc -> acc) -> acc -> BiDict a b -> acc
Fold over the key-value pairs in a dictionary from highest key to lowest key.
getAges users =
Dict.foldr addAge [] users
addAge _ user ages =
user.age :: ages
-- getAges users == [28,19,33]
filter : (a -> b -> Basics.Bool) -> BiDict a b -> BiDict a b
Keep only the key-value pairs that pass the given test.
partition : (a -> b -> Basics.Bool) -> BiDict a b -> ( BiDict a b, BiDict a b )
Partition a dictionary according to some test. The first dictionary contains all key-value pairs which passed the test, and the second contains the pairs that did not.
union : BiDict a b -> BiDict a b -> BiDict a b
Combine two dictionaries. If there is a collision, preference is given to the first dictionary.
intersect : BiDict a b -> BiDict a b -> BiDict a b
Keep a key-value pair when its key appears in the second dictionary. Preference is given to values in the first dictionary.
diff : BiDict a b -> BiDict a b -> BiDict a b
Keep a key-value pair when its key does not appear in the second dictionary.
merge : (a -> b1 -> acc -> acc) -> (a -> b1 -> b2 -> acc -> acc) -> (a -> b2 -> acc -> acc) -> BiDict a b1 -> BiDict a b2 -> acc -> acc
The most general way of combining two dictionaries. You provide three accumulators for when a given key appears:
You then traverse all the keys from lowest to highest, building up whatever you want.