Ein Dict in Elm ist ein unveränderliches Wörterbuch aus null oder mehr Schlüssel-Wert-Paaren.
Wörterbücher werden mit Funktionen und Operatoren bearbeitet, die im Dict-Modul definiert sind.
Typannotationen für Wörterbücher schreibt man wie folgt
Dict String (List Int) --> a dict with String keys and List Int values
Dict Int String --> a dict with Int keys and String values
Wörterbücher können wie folgt erstellt werden:
empty : Dict Int String
empty = Dict.empty
singleValue = Dict.singleton 5 "Value for key 5" --> Dict Int String
twoValues = Dict.fromList [ ( "Alice", 0 ), ( "Bob", 1 ) ] --> Dict String Int
Einträge können mit get abgerufen werden.
Da ein Schlüssel im Wörterbuch vorhanden sein kann oder nicht, wird das Ergebnis in ein Maybe verpackt.
alice = Dict.fromList [ ( 0, "Alice" ) ]
keyExists = Dict.get 0 alice --> Just "Alice"
keyNotPresent = Dict.get 1 alice --> Nothing
Einträge können mit insert hinzugefügt werden.
Einträge für Schlüssel, die bereits im Wörterbuch vorhanden sind, werden ersetzt.
alice = Dict.fromList [ ( "Alice", 0 ) ]
aliceAndBob = Dict.insert "Bob" 1 alice --> Dict.fromList [ ( "Alice", 0 ), ( "Bob", 1 ) ]
aliceAndAlice = Dict.insert "Alice" 1 alice --> Dict.fromList [ ( "Alice", 1 ) ]
Einträge können mit update aktualisiert werden.
Wenn der Schlüssel nicht existiert, wird die Update-Funktion mit Nothing aufgerufen.
alice = Dict.fromList [ ( 0, "Alice" ) ]
aliceUpperCase = Dict.update 0 (Maybe.map String.toUpper) alice --> Dict.fromList [ ( 0, "ALICE" ) ]
aliceNoCase = Dict.update 0 (\_ -> Nothing) alice --> Dict.empty
bobUpperCase = Dict.update 1 (\_ -> Just "BOB") alice --> Dict.fromList [ ( 0, "Alice" ), ( 1, "BOB" ) ]
bobNoCase = Dict.update 1 (\_ -> Nothing) alice --> Dict.fromList [ ( 0, "Alice" ) ]
Einträge können mit remove entfernt werden.
Wenn der Schlüssel nicht existiert, ändert sich nichts.
alice = Dict.fromList [ ( 0, "Alice" ) ]
stillAlice = Dict.remove 1 --> ( 0, "Alice" )
empty = Dict.remove 0 alice --> Dict.empty
Eine Liste von Schlüssel-Wert-Paaren kann mit fromList in ein Wörterbuch umgewandelt werden.
alice = Dict.fromList [ ( 0, "Bob" ), ( 0, "Alice" ) ]
--> True Dict.fromList [ ( 0, "Alice" ) ]
Einträge können mit toList in eine Liste umgewandelt werden.
Die Liste ist nach den Schlüsseln sortiert.
aliceAndBob = Dict.fromList [ ( 1, "Alice" ), ( 0, "Bob" ) ]
bobAndAlice = Dict.toList aliceAndBob
--> [ ( 0, "Bob" ), ( 1, "Alice" ) ]
Mehrere Einträge können mit filter entfernt werden.
aliceAndBob = Dict.fromList [ ( "Alice", 1 ), ( "Bob", 0 ) ]
bob = Dict.filter (\name count -> name == "Bob") aliceAndBob --> Dict.fromList [ ( "Bob", 0 ) ]
Einträge können mit map transformiert werden.
alice = Dict.fromList [ ( "Alice", 0 ) ]
empty = Dict.map (\player count -> count + 1) alice --> Dict.fromList [ ( "Alice", 1 ) ]
Wörterbücher können mit merge kombiniert bzw. transformiert werden.
aliceAndBob = Dict.fromList [ ( "Alice", 1 ), ( "Bob", 1 ) ]
bobAndCedd = Dict.fromList [ ( "Bob", 1 ), ( "Cedd", 1 ) ]
firstDictCountsDouble = Dict.merge
-- when only in aliceAndBob
(\name count mergedCounts -> Dict.insert name (2 * count) mergedCounts)
-- when in aliceAndBob and bobAndCedd
(\name aliceAndBobCount bobAndCeddCount mergedCounts -> Dict.insert name (2 * aliceAndBobCount + bobAndCeddCount) mergedCounts)
-- when only in bobAndCedd
(\name count mergedCounts -> Dict.insert name count mergedCounts)
-- the two dicts to merge
aliceAndBob
bobAndCedd
-- the initial state of the merge
Dict.empty
--> Dict.fromList [ ( "Alice", 2 ), ( "Bob", 3 ), ( "Cedd", 1 ) ]
Jede Funktion oder jeder Operator, der ein Wörterbuch zu verändern scheint (etwa beim Hinzufügen eines Elements), gibt tatsächlich ein neues Wörterbuch zurück. Die Performance ist meistens kein Problem, weil die Implementierung unnötige Allokationen und Kopien vermeidet.
In Elm ist es im Allgemeinen besser, Abstraktionen auf höherer Ebene wie Dict.map, Dict.filter und Dict.merge zu verwenden statt Abstraktionen auf niedrigerer Ebene wie Dict.get und Dict.remove. Natürlich hängt das vom Kontext ab.
Deine Aufgabe ist es, eine Liste der Torschützen eines Spiels zu nehmen und zu zählen, wie viele Tore jeder Spieler erzielt hat.
PlayerName ist ein Typalias für String, damit der Code leichter zu lesen ist und damit diese Verwendung von String von anderen Verwendungen von String unterschieden werden kann.
Implementiere zuerst updateGoalCountForPlayer, um die Toranzahl für einen Spieler zu initialisieren oder zu erhöhen.
Implementiere dann die Funktion aggregateScorers, um zu zählen, wie viele Tore jeder Spieler erzielt hat, indem du updateGoalCountForPlayer verwendest.
Diese Funktion nimmt eine List PlayerName (die Namen der Spieler, die die Tore erzielt haben; sie kann doppelte Spielernamen enthalten) und gibt ein Dict PlayerName Int zurück, das alle Spieler aus der Liste zusammen mit der Anzahl der erzielten Tore enthält.
aggregateScorers [ "Betty", "Cedd", "Betty" ]
--> Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ]
Implementiere die Funktion removeInsignificantPlayers, um alle Spieler herauszufiltern, die weniger Tore als der Schwellenwert erzielt haben.
removeInsignificantPlayers 2 (Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ] )
--> Dict.fromList [ ( "Betty", 2 ) ]
Implementiere die Funktion resetPlayerGoalCount, um die erzielten Tore eines Spielers auf null zurückzusetzen.
resetPlayerGoalCount "Cedd" (Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ] )
--> Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 0 ) ]
Implementiere die Funktion formatPlayer, um die Toranzahl für einen einzelnen Spieler als String zu formatieren. Wenn der Spieler nicht im Dict vorhanden ist, gehe davon aus, dass seine Toranzahl null ist.
formatPlayer "Betty" (Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ] )
--> "Betty: 2"
Implementiere die Funktion formatPlayers, um die Toranzahl für alle Spieler als String zu formatieren. Die Spieler sollten nach Spielernamen sortiert sein.
formatPlayers (Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ] )
--> "Betty: 2, Cedd: 1"
Implementiere die Funktion combineGames, die die Gesamtzahl der Tore zählt, die jeder Spieler in beiden Spielen erzielt hat.
combine Games
(Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ] )
(Dict.fromList [ ( "Betty", 2 ), ( "Mario", 3 ) ] )
--> Dict.fromList [ ( "Betty", 4 ), ( "Cedd", 1 ), ( "Mario", 3 ) ]
Melde dich bei Exercism an, um Elm mit 28 Konzepte110 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.