A KeysSet with no elements inside,
promising that given aspects are unique across all elements.
See Uniqueness
KeysSet.promising [ unique .email ]
|> KeysSet.insert
{ username = "ben", email = "[email protected]" }
|> KeysSet.insert
{ username = "mai", email = "[email protected]" }
--> is not inserted.
--> There's already an element where .email is "[email protected]"Elements that are inserted must not contain functions, json or regexes. Elm will crash trying to see if they are equal.
Check 2 elements if they are equal in a specified aspect. See unique
uniqueInCasedLetter =
[ unique .inAlphabet
, unique .lowercase
, unique .uppercase
]
KeysSet.promising uniqueInCasedLetter
|> KeysSet.insert
{ inAlphabet = 0, lowercase = 'a', uppercase = 'A' }
|> KeysSet.insert
{ inAlphabet = 0, lowercase = 'b', uppercase = 'B' }
--> isn't inserted. There's already an element where .inAlphabet is 0.Check elements if some aspect is not the same.
unique .name
{ name = "smile", symbol = '😊' }
{ symbol = '🙂', name = "smile" }
--> { areUnique = False }
unique .symbol
{ name = "smile", symbol = '😊' }
{ symbol = '🙂', name = "smile" }
--> { areUnique = True }
unique (\person -> ( person.firstName, person.lastName ))
{ lastName = "jimmy", firstName = "petter", ... }
{ lastName = "jimmy", firstName = "greg", ... }
--> { areUnique = True }in KeysSet
KeysSet.promising [ unique .email ]
|> KeysSet.insert
{ username = "ben", email = "[email protected]" }
|> KeysSet.insert
{ username = "mai", email = "[email protected]" }
--> is not inserted.
--> There's already an element where .email is "[email protected]"How can you know if each element in aKeysSet can also be found in bKeysSet?
letterCodes =
KeysSet.insertAll
[ { letter = 'a', code = 97 }
, { letter = 'b', code = 98 }
]
(KeysSet.promising
[ unique .letter, unique .code ]
)
fancyCompetingLetterCodes =
KeysSet.promising
[ unique .code, unique .letter ]
|> KeysSet.insert { code = 98, letter = 'b' }
|> KeysSet.insert { code = 97, letter = 'a' }
letterCodes == fancyCompetingLetterCodes
--> elm crashesBecause a KeysSet's Uniqueness is defined as functions.
(letterCodes |> KeysSet.toList)
== (fancyCompetingLetterCodes |> KeysSet.toList)
--> FalseEven though both contain the same elements but in a different order.
→ Don't use
==to compareKeysSets
The keys can be non-comparable. There is no obvious order. → You shouldn't rely on order when using functions like
foldortoList.
Instead, use
KeysSet.equal
letterCodes
fancyCompetingLetterCodes
--> TrueWhether there are no elements inside.
KeysSet.promising [ unique .name ]
|> KeysSet.isEmpty
--> True
KeysSet.promising [ unique .name ]
|> KeysSet.insertAll []
|> KeysSet.isEmpty
--> True
KeysSet.promising [ unique .name ]
|> KeysSet.insert { name = "pete" }
|> KeysSet.isEmpty
--> FalseTry to find an element where a given aspect of it matches a given value.
casedLetters =
KeysSet.promising
[ unique .lowercase, unique .uppercase ]
|> KeysSet.insertAll
[ { lowercase = 'a', uppercase = 'A' }
, { lowercase = 'b', uppercase = 'B' }
]
lowercase char =
casedLetters
|> KeysSet.at .uppercase char
|> Maybe.map .lowercase
uppercase char =
casedLetters
|> KeysSet.at .lowercase char
|> Maybe.map .uppercaseIf the given aspect isn't promised to be unique,
at will find the most recently inserted element where the given aspect matches the given value.
ratedOperators =
KeysSet.promising
[ unique .symbol, unique .name ]
|> KeysSet.insertAll
[ { rating = 0.5, symbol = "<", name = "lt" }
, { rating = 0.5, symbol = ">", name = "gt" }
]
KeysSet.at .rating 0.5 ratedOperators
--> { rating = 0.5, symbol = ">", name = "gt" }
--> |> JustHow many elements there are.
KeysSet.promising [ unique identity ]
|> KeysSet.insertAll (List.range 0 41)
|> KeysSet.size
--> 42Whether this element is considered unique / would it be inserted.
letters =
KeysSet.promising
[ unique .lowercase, unique .uppercase ]
|> KeysSet.insertAll
[ { lowercase = 'a', uppercase = 'A' }
, { lowercase = 'b', uppercase = 'B' }
]
letters
|> KeysSet.isUnique
{ lowercase = 'b', uppercase = 'C' }
--> False
-- .lowercase 'b' already exists
letters
|> KeysSet.isUnique
{ lowercase = 'c', uppercase = 'A' }
--> False
-- .uppercase 'A' already exists
letters
|> KeysSet.isUnique
{ lowercase = 'c', uppercase = 'C' }
--> TrueWhether all elements pass a test.
KeysSet.promising
[ unique .username, unique .email ]
|> KeysSet.insertAll
[ { username = "fred", priority = 1, email = "[email protected]" }
, { username = "gria", priority = 3, email = "[email protected]" }
]
|> KeysSet.all (\user -> user.priority < 4)
--> TrueWhether there is least one element that passes a test.
KeysSet.promising
[ unique .username, unique .email ]
|> KeysSet.insertAll
[ { username = "fred", priority = 1, email = "[email protected]" }
, { username = "gria", priority = 3, email = "[email protected]" }
]
|> KeysSet.any (\user -> user.priority > 4)
--> False
member needle =
KeysSet.any ((==) needle)Put an element into the KeysSet.
If there is already an element where some aspect that is promised to be unique is equal, (see Uniqueness), the KeysSet remains unchanged.
KeysSet.promising
[ unique .lowercase, unique .uppercase ]
|> KeysSet.insert
{ lowercase = 'b', uppercase = 'B', rating = 0.5 }
--> is inserted
|> KeysSet.insert
{ lowercase = 'a', uppercase = 'A', rating = 0.5 }
--> is inserted
-- .rating is not specified as unique
|> KeysSet.insert
{ lowercase = 'b', uppercase = 'C', rating = 0 }
--> is ignored
-- .lowercase 'b' already exists
|> KeysSet.insert
{ lowercase = 'c', uppercase = 'A', rating = 0 }
--> is ignored
-- .uppercase 'A' already exists
|> KeysSet.insert
{ lowercase = 'c', uppercase = 'C', rating = 0.6 }
--> is insertedConveniently insert a list of elements. See insert.
KeysSet.promising
[ unique .open, unique .closed ]
|> KeysSet.insertAll
[ { open = '(', closed = ')' }
, { open = '{', closed = '}' }
]
--> KeysSet.promising [ unique .open, unique .closed ]
--> |> KeysSet.insert { open = '(', closed = ')' }
--> |> KeysSet.insert { open = '{', closed = '}' }Remove the element where a given aspect of the element matches a given value.
openClosedBrackets =
KeysSet.promising
[ unique .open, unique .closed ]
|> KeysSet.insert
{ open = "(", closed = ")" }
openClosedBrackets
|> KeysSet.remove .open ")"
--> no change
-- .open is never ")"
openClosedBrackets
|> KeysSet.remove .closed ")"
--> removes { open = "(", closed = ")" }If there the checked aspect isn't promised to be unique, remove acts as a filter.
KeysSet.promising
[ unique .open, unique .closed ]
|> KeysSet.insertAll
[ { open = "[", closed = "]", meaning = List }
, { open = "<", closed = ">", meaning = Custom }
, { open = "\\", closed = "/", meaning = Custom }
]
|> KeysSet.remove .meaning Custom
--> only { open = "[", closed = "]", meaning = List } remainsIf filtering is your intention, use KeysSet.when.
Change the element with the matching aspect based on its current value.
KeysSet.promising
[ unique .username, unique .email ]
|> KeysSet.insertAll
[ { username = "fred", priority = 1, email = "[email protected]" }
, { username = "gria", priority = 3, email = "[email protected]" }
]
|> KeysSet.update .username
"fred"
(\user -> { user | priority = p.priority + 3 })If this aspect isn't unique, all elements with the matching aspect are updated.
KeysSet.promising [ unique .email ]
|> KeysSet.insertAll
[ { username = "fred", priority = 1, email = "[email protected]" }
, { username = "fred", priority = 3, email = "[email protected]" }
]
|> KeysSet.update .username
"fred"
(\user -> { user | priority = p.priority + 3 })Every fred gets a higher priority!
Change every element based on its current value.
rankUpAllUsers =
KeysSet.updateAll
(\user -> { user | rank = user.rank + 1 })If aspects that are promised to be unique become the same for 2 elements, the more recently inserted element is chosen.
Use map if your function changes the type of the element.
Only keep elements that satisfy a test.
operators =
KeysSet.promising
[ unique .symbol, unique .name ]
|> KeysSet.insertAll
[ { symbol = ">", name = "gt" }
, { symbol = "<", name = "lt" }
, { symbol = "==", name = "eq" }
]
singleCharOperators =
operators
|> KeysSet.when
(.symbol >> String.length >> (==) 1)
--> KeysSet.promising
--> [ unique .symbol, unique .name ]
--> |> KeysSet.insertAll
--> [ { symbol = ">", name = "gt" }
--> , { symbol = "<", name = "lt" }
--> ]Reduce the elements from most recently to least recently inserted element.
The keys can be non-comparable. There is no obvious order.
→ You shouldn't rely on order when using functions like
foldortoList.
brackets =
KeysSet.promising
[ unique .open, unique .closed ]
|> KeysSet.insertAll
[ { open = '(', closed = ')' }
, { open = '{', closed = '}' }
]
openingAndClosing =
brackets
|> KeysSet.fold
(\{ open, closed } ->
(::) (String.fromList [ open, closed ])
)
[]
--> []
--> |> (::) (String.fromList [ '{' '}' ])
--> |> (::) (String.fromList [ '(' ')' ])The List containing all elements from most recently (= head) to least recently inserted element.
The keys can be non-comparable. There is no obvious order.
→ You shouldn't rely on order when using functions like
foldortoList.
mostRecentlyInserted =
List.head << KeysSet.toList
KeysSet.promising
[ unique .open, unique .closed ]
|> KeysSet.insertAll
[ { open = '(', closed = ')' }
, { open = '{', closed = '}' }
]
|> KeysSet.toList
--> [ { open = '{', closed = '}' }
--> , { open = '(', closed = ')' }
--> ]Alter every element based on its current value.
digitNames =
KeysSet.promising
[ unique .number, unique .name ]
|> KeysSet.insertAll
[ { number = 0, name = "zero" }
, { number = 1, name = "one" }
]
mathSymbolNames =
digitNames
|> KeysSet.map
(\{ number, name } ->
{ symbol = String.fromInt number, name = name }
)
[ unique .symbol, unique .name ]
|> KeysSet.insert { symbol = "+", name = "plus" }If the type doesn't change, use KeysSet.updateAll.
Unsorted data structure that lets you specify aspects that are checked to be unique across all elements.
If you have a key and the aspect to check if it matches, you can find the matching element: