Have many keys to lookup values.
Let's compare
DictYou want the value where the key is
1?
0 : 🏡
--> 1 : 🏚
2 : 🏚
the key is unique among all itemsGoing through while comparing your key.
the value is 🏚 where the key is `1`KeysDictFirst of all, get used to some names
keepInParserPipelineOperator=
{ operator= "|=" --no operator overloading wanted!
, origin= ElmRepoPackage "parser" --is the same for |.
}door .operator
--is a promise, that the operator value is never the same for two houses.So... If you have a key and the type of door it could match, you can find the only matching house and enter.
You want to enter the house where
🗝️is1?
🔑= 0, 🏠= 🏚, 🗝️= 2
🔑= 2, 🏠= 🏡, 🗝️= 0
🔑= 1, 🏠= 🏚, 🗝️= 1 <--
🔑, 🗝️: doors you can "open" with a key unique across all housesGoing through while checking every house, if the
🗝️matches.
🔑= 1, 🏠= 🏚, 🗝️= 1 where 🗝️ is 1 You want to enter the house where
🔑is0?
--> 🔑= 0, 🏠= 🏚, 🗝️= 2
🔑= 2, 🏠= 🏡, 🗝️= 0
🔑= 1, 🏠= 🏚, 🗝️= 1
🔑, 🗝️: doors you can "open" with a key unique across all housesGoing through while checking every house, if the
🔑matches.
🔑= 0, 🏠= 🏚, 🗝️= 2 where 🔑 is 0A KeysDict with no houses inside, promising that given aspects are unique across all houses (see Uniqueness).
How can you know if each house in aKeysDict can also be found in bKeysDict?
letterCodes=
[ { letter= 'a', code= 97 }
, { letter= 'b', code= 98 }
]
|>List.foldl putUp
(KeysDict.enterableBy
[ door .letter, door .code ]
)
fancyCompetingLetterCodes=
KeysDict.enterableBy
[ door .code, door .letter ]
|>putUp { code= 98, letter= 'b' }
|>putUp { code= 97, letter= 'a' }
(==) letterCodes fancyCompetingLetterCodes
--> elm crashesBecause a KeysDict's Uniqueness is defined as functions.
(==)
(houses letterCodes)
(houses fancyCompetingLetterCodes)
--> FalseEven though both contain the same houses but in a different order.
Don't use
==to compareKeysDicts
With non-comparable types, thinking about order doesn't make much sense. You shouldn't rely on it when using functions like folds or
houses.
Instead, you should use
KeysDict.equal
letterCodes
fancyCompetingLetterCodes
--> TrueHouses must not contain functions or json. Elm will crash trying to see if they are equal.
Just the house where door of the house matches the key;
if no such house is found, Nothing.
casedLetters=
KeysDict.enterableBy
[ door .lowercase, door .uppercase ]
|>putUp { lowercase= 'a', uppercase= 'A' }
|>putUp { lowercase= 'b', uppercase= 'B' }
lowercase char=
casedLetters
|>enterBy { door= .uppercase, key= char }
|>Maybe.map .lowercase
uppercase char=
casedLetters
|>enterBy { door= .lowercase, key= char }
|>Maybe.map .uppercaseNote: If keys of door aren't promised to be unique,
enterBy will find the most recently inserted house where door of the house matches the key.
ratedCasedLetters=
KeysDict.enterableBy
[ door .lowercase, door .uppercase ]
|>putUp { rating= 0.5, lowercase= 'a', uppercase= 'A' }
|>putUp { rating= 0.5, lowercase= 'b', uppercase= 'B' }
enterBy { door= .rating, key= 0.5 } ratedCasedLetters
--> { rating= 0.5, lowercase= 'b', uppercase= 'B' }How many houses there are.
List.foldl putIn
(KeysDict.enterableBy
[ door .number, door .following ]
)
(List.map (\i-> { number= i, following= i +1 })
(List.range 0 41)
)
|>countHouses
--> 42Put a house into keysDict. Keys must not contain functions or json. Elm will crash trying to see if they match.
If there is already a house with the same key is already present, (see Uniqueness), the KeysDict remains unchanged.
KeysDict.enterableBy
[ door .lowercase, door .uppercase ]
|>putUp { lowercase= 'b', uppercase= 'B', rating= 0.5 }
--put up
|>putUp { lowercase= 'a', uppercase= 'A', rating= 0.5 }
--put up, because rating is not a key
|>putUp { lowercase= 'b', uppercase= 'C', rating= 0 }
--ignored, the .lowercase already exists
|>putUp { lowercase= 'c', uppercase= 'A', rating= 0 }
--ignored, the .uppercase already exists
|>putUp { lowercase= 'c', uppercase= 'C', rating= 0.6 }
--put upRemove the house where door of the house matches the key.
If the key does not exist, the KeysDict is unchanged
openClosedBrackets=
KeysDict.enterableBy
[ door .open, door .closed ]
|>putUp { open= "(", closed= ")" }
openClosedBrackets
|>tearDown { door= .open, key= ")" }
--unchanged, ")" does not exist as a .open key
|>tearDown { door= .open, key= "(" }
--> KeysDict.enterableBy
--> [ door .open, door .closed ]
openClosedBrackets
|>tearDown { door= .closed, key= "(" }
--unchanged, "(" does not exist as a .closed key
|>tearDown { door= .closed, key= ")" }
--> KeysDict.enterableBy
--> [ door .open, door .closed ]Notice: If there is no promise of Uniqueness for door, remove acts as a normal filter.
KeysDict.enterableBy
[ door .open, door .closed ]
|>putUp { open= "(", closed= ")", meaning= Nothing }
|>putUp { open= "[", closed= "]", meaning= Just List }
|>putUp { open= "<, closed= ">", meaning= Nothing }
|>tearDown { door= .meaning, key= Nothing }
--> KeysDict.enterableBy
--> [ door .open, door .closed ]
--> |>putUp { open= "[", closed= "]", meaning= Just List }Reduce the houses from most recently to least recently inserted house.
With non-comparable types, thinking about order doesn't make much sense. You shouldn't rely on it when using functions like folds or
houses.
brackets=
KeysDict.enterableBy
[ door .open, door .closed ]
|>putUp { open= '(', closed= ')' }
|>putUp { open= '{', closed= '}' }
openingAndClosing=
brackets
|>foldHouses
(\{ open, closed }->
(::) (String.fromList [ open, closed ])
)
[]
--> []
--> |>(::) (String.fromList [ '{' '}' ])
--> |>(::) (String.fromList [ '(' ')' ])Map all houses.
digitNames=
KeysDict.enterableBy
[ door .number, door .name ]
|>putUp { number= 0, name= "zero" }
|>putUp { number= 1, name= "one" }
mathSymbolNames=
digitNames
|>mapHouses [ door .symbol, door .name ]
(\{ number, name }->
{ symbol= String.fromInt number, name= name }
)
|>putUp { symbol= "+", name= "plus" }The List containing all houses from most recently (= head) to least recently inserted house.
With non-comparable types, thinking about order doesn't make much sense. You shouldn't rely on it when using functions like folds or
houses.
isEmpty=
List.isEmpty <<houses
mostRecentlyInserted=
List.head <<houses
removeMostRecentlyInserted keysDict=
case houses keysDict of
_ ::rest->
rest
[]->
keysDictConvert a KeysDict to an association-Dict.
casedLetters=
KeysDict.enterableBy
[ door .lowercase, door .uppercase ]
|>putUp { uppercase= 'A', lowercase= 'a' }
|>putUp { uppercase= 'B', lowercase= 'b' }
lowerFromUppercase=
KeysDict.toDict { key= .uppercase, value= .lowercase }
casedLettersSerialize a KeysDict.
type alias NamedNumber=
{ name: String
, number: Int
}
namedNumberCodec=
Serialize.record NamedNumber
|>Serialize.field .name Decode.string
|>Serialize.field .number Decode.int
|>Serialize.finishRecord
namedNumberKeysDictCodec=
KeysDict.codec namedNumberCodec
[ door .number, door .name ]
someKeysDict=
KeysDict.enterableBy
[ door .number, door .name ]
|>putUp { number= 1, name= "one" }
|>putUp { number= 2, name= "two" }
Serialize.encodeToJson
(NamedNumberKeyDictCodec someKeysDict)
|>Json.Encode.encode 1
--> """
--> [
--> {
--> \"number\": 2,
--> \"name\": "two"
--> },
--> {
--> \"number\": 1,
--> \"name\": "one"
--> }
--> ]
--> """
"""
[
{
\"number\": 2,
\"name\": "two"
},
{
\"number\": 1,
\"name\": "one"
}
]
"""
|>Json.Decode.decodeString
(Serialize.decodeFromJson
namedNumberKeysDictCodec
)
--> Ok
--> (KeysDict.enterableBy
--> [ door .number, door .name ]
--> |>putUp { number= 1, name= "one" }
--> |>putUp { number= 2, name= "two" }
--> )
Unsorted data structure, which promises
Uniquenessfor multiple doors.This allows for a special kind of access:
Read the module doc for more!