A dictionary mapping unique keys to multiple values, allowing for modelling one-to-many relationships.
Example usage:
oneToMany : MultiDict String Int
oneToMany =
MultiDict.empty
|> MultiDict.insert "A" 1
|> MultiDict.insert "B" 2
|> MultiDict.insert "C" 3
|> MultiDict.insert "A" 2
MultiDict.get "A" oneToMany
--> Set.fromList [1, 2]
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 MultiDict a b =
Dict a (Set b) -- just a normal Dict!
toDict : MultiDict a b -> AssocList.Dict a (AssocSet.Set b)
Convert MultiDict into a Dict. (Throw away the reverse mapping.)
fromDict : AssocList.Dict a (AssocSet.Set b) -> MultiDict a b
Convert Dict into a MultiDict. (Compute the reverse mapping.)
empty : MultiDict a b
Create an empty dictionary.
singleton : a -> b -> MultiDict a b
Create a dictionary with one key-value pair.
insert : a -> b -> MultiDict a b -> MultiDict a b
Insert a key-value pair into a dictionary. Replaces value when there is a collision.
update : a -> (AssocSet.Set b -> AssocSet.Set b) -> MultiDict a b -> MultiDict a b
Update the value of a dictionary for a specific key with a given function.
remove : a -> b -> MultiDict a b -> MultiDict a b
Remove a single key-value pair from a dictionary. If the key is not found, no changes are made.
removeAll : a -> MultiDict a b -> MultiDict a b
Remove all key-value pairs for the given key from a dictionary. If the key is not found, no changes are made.
isEmpty : MultiDict a b -> Basics.Bool
Determine if a dictionary is empty.
isEmpty empty == True
member : a -> MultiDict a b -> Basics.Bool
Determine if a key is in a dictionary.
get : a -> MultiDict a b -> AssocSet.Set 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 : MultiDict a b -> Basics.Int
Determine the number of key-value pairs in the dictionary.
keys : MultiDict 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 : MultiDict 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 : MultiDict a b -> List ( a, AssocSet.Set b )
Convert a dictionary into an association list of key-value pairs, sorted by keys.
fromList : List ( a, AssocSet.Set b ) -> MultiDict a b
Convert an association list into a dictionary.
fromFlatList : List ( a, b ) -> MultiDict a b
Convert an association list into a dictionary.
fromFlatList
[ ( "foo", 1 )
, ( "bar", 2 )
, ( "foo", 3 )
]
results in the same dict as
fromList
[ ( "foo", Set.fromList [ 1, 3 ] )
, ( "bar", Set.fromList [ 2 ] )
]
map : (a -> b1 -> b2) -> MultiDict a b1 -> MultiDict a b2
Apply a function to all values in a dictionary.
foldl : (a -> AssocSet.Set b -> acc -> acc) -> acc -> MultiDict 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 -> AssocSet.Set b -> acc -> acc) -> acc -> MultiDict 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) -> MultiDict a b -> MultiDict a b
Keep only the mappings that pass the given test.
partition : (a -> AssocSet.Set b -> Basics.Bool) -> MultiDict a b -> ( MultiDict a b, MultiDict 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 : MultiDict a b -> MultiDict a b -> MultiDict a b
Combine two dictionaries. If there is a collision, preference is given to the first dictionary.
intersect : MultiDict a b -> MultiDict a b -> MultiDict 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 : MultiDict a b -> MultiDict a b -> MultiDict a b
Keep a key-value pair when its key does not appear in the second dictionary.
merge : (a -> AssocSet.Set b1 -> acc -> acc) -> (a -> AssocSet.Set b1 -> AssocSet.Set b2 -> acc -> acc) -> (a -> AssocSet.Set b2 -> acc -> acc) -> MultiDict a b1 -> MultiDict 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.