escherlies / elm-ix-dict / IxDict

A Dict data structure that derives keys from values. The keys can be any comparable type. This includes Int, Float, Time, Char, String, and tuples or lists of comparable types. Since it uses the underlying core/Dict module, insert, remove, and query operations all take O(log n) time.

Indexed Dictionaries


type IxDict k v

A dictionary of keys and values wrapped with a keyFn (v -> k) to derive keys from that dictionary.

Create

toDict : IxDict k v -> Dict k v

Convert an indexed dictionary into a normal dictionary

fromListBy : (v -> comparable) -> List v -> IxDict comparable v

Create an indexed dictionary from list by providing a key fn.

users : IxDict.IxDict String User
users =
    IxDict.fromListBy .id
        [ User "alice" "Alice"
        , User "bob" "Bob"
        ]

type alias User =
    { id : String, name : String }

updated : IxDict.IxDict String User
updated =
    users
        |> IxDict.insert (User "charlie" "Charlie")
        |> IxDict.remove "bob"

fromDictBy : (v -> comparable) -> Dict k v -> IxDict comparable v

Create an indexed dictionary from a normal dictionary by providing a key fn. Esentially gets the dict values and uses fromListBy:

fromDictBy : (v -> comparable) -> Dict k v -> IxDict comparable v
fromDictBy keyFn =
    fromListBy keyFn << Dict.values

See fromListBy on how to use it.

empty : (v -> comparable) -> IxDict comparable v

Create an empty indexed dictionary using a keyFn

singleton : (v -> comparable) -> v -> IxDict comparable v

Create a dictionary with one key-value pair and a keyFn

Manipulate

insert : v -> IxDict comparable v -> IxDict comparable v

Insert a value into an indexed dictionary. Replaces value when there is a collision.

remove : comparable -> IxDict comparable v -> IxDict comparable v

Remove a key-value pair from the dictionary. If the key is not found, no changes are made.

Query

isEmpty : IxDict k v -> Basics.Bool

Determine if a dictionary is empty.

member : comparable -> IxDict comparable v -> Basics.Bool

Determine if a key is in a dictionary.

memberByIx : v -> IxDict comparable v -> Basics.Bool

Determine if a value is in a dictionary, only by comparing keys.

memberExact : v -> IxDict comparable v -> Basics.Bool

Determine if a value is structually in a dictionary.

get : comparable -> IxDict comparable v -> Maybe v

Get the value associated with a key.

size : IxDict k v -> Basics.Int

Determine the number of key-value pairs in the dictionary.

Lists

keys : IxDict k v -> List k

Get all of the keys in a dictionary, sorted from lowest to highest.

values : IxDict k v -> List v

Get all of the values in a dictionary, in the order of their keys.

toList : IxDict k v -> List ( k, v )

Convert a dictionary into an association list of key-value pairs, sorted by keys.

Transform

map : (comparable -> b -> b) -> IxDict comparable b -> IxDict comparable b

Map a function onto a ixDict, creating a new ixDict with no duplicates.

This operation is not structure-preserving for sets, so is not a valid Functor. An example case: mapping const x over a ixDict with n > 0 elements will result in a ixDict with one element.

mapWith : (b -> comparable) -> (comparable -> a -> b) -> IxDict comparable a -> IxDict comparable b

Transform values and rebuild the dict with a new keyFn

foldl : (k -> v -> b -> b) -> b -> IxDict k v -> b

Fold over the key-value pairs in an indexed dictionary from lowest key to highest key.

foldr : (k -> v -> b -> b) -> b -> IxDict k v -> b

Fold over the key-value pairs in an indexed dictionary from highest key to lowest key.

filter : Basics.Never -> a

Filter... use keep or reject instead.

Because, what does it filter? Do you want the filtered product like coffee (in this case, use reject) or the remaining good part like gold pannig (in this case, use keep)

keep : (comparable -> v -> Basics.Bool) -> IxDict comparable v -> IxDict comparable v

Keep only the key-value pairs that pass the given test.

reject : (comparable -> v -> Basics.Bool) -> IxDict comparable v -> IxDict comparable v

Reject all key-value pairs that for a given test

partition : (comparable -> v -> Basics.Bool) -> IxDict comparable v -> ( IxDict comparable v, IxDict comparable v )

Partition an indexed 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.

Combine

union : IxDict comparable v -> IxDict comparable v -> IxDict comparable v

Combine two indexed dictionaries. If there is a collision, preference is given to the first indexed dictionary.

intersect : IxDict comparable v -> IxDict comparable v -> IxDict comparable v

Keep a key-value pair when its key appears in the second indexed dictionary. Preference is given to values in the first indexed dictionary.

diff : IxDict comparable v -> IxDict comparable v -> IxDict comparable v

Keep a key-value pair when its key does not appear in the second indexed dictionary.

Convenience

emptyFromTuple : IxDict comparable ( comparable, b )

Uses Tuple.first as keyFn

emptyFromId : IxDict comparable { a | id : comparable }

Uses .id as keyFn

singletonFromTuple : ( comparable, b ) -> IxDict comparable ( comparable, b )

Uses Tuple.first as keyFn

singletonFromId : { a | id : comparable } -> IxDict comparable { a | id : comparable }

Uses .id as keyFn