Un Dict en Elm est un dictionnaire immuable de zéro ou plusieurs paires clé-valeur.
Les Dict se manipulent à l'aide de fonctions et d'opérateurs définis dans le module Dict.
Les annotations de type des dictionnaires s'écrivent comme suit :
Dict String (List Int) --> a dict with String keys and List Int values
Dict Int String --> a dict with Int keys and String values
On peut créer des dictionnaires comme suit :
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
On peut récupérer des éléments avec get.
Comme une clé peut être présente ou non dans le dictionnaire, le résultat est enveloppé dans un Maybe.
alice = Dict.fromList [ ( 0, "Alice" ) ]
keyExists = Dict.get 0 alice --> Just "Alice"
keyNotPresent = Dict.get 1 alice --> Nothing
On peut ajouter des éléments avec insert.
Les éléments dont la clé est déjà présente dans le dictionnaire sont remplacés.
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 ) ]
On peut mettre à jour des éléments avec update.
Si la clé n'existe pas, la fonction de mise à jour est appelée avec Nothing.
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" ) ]
On peut supprimer des éléments avec remove.
Si la clé n'existe pas, rien n'est modifié.
alice = Dict.fromList [ ( 0, "Alice" ) ]
stillAlice = Dict.remove 1 --> ( 0, "Alice" )
empty = Dict.remove 0 alice --> Dict.empty
On peut convertir une liste de paires clé-valeur en dictionnaire avec fromList.
alice = Dict.fromList [ ( 0, "Bob" ), ( 0, "Alice" ) ]
--> True Dict.fromList [ ( 0, "Alice" ) ]
On peut convertir des éléments en liste avec toList.
La liste est triée par les clés.
aliceAndBob = Dict.fromList [ ( 1, "Alice" ), ( 0, "Bob" ) ]
bobAndAlice = Dict.toList aliceAndBob
--> [ ( 0, "Bob" ), ( 1, "Alice" ) ]
On peut supprimer plusieurs éléments avec filter.
aliceAndBob = Dict.fromList [ ( "Alice", 1 ), ( "Bob", 0 ) ]
bob = Dict.filter (\name count -> name == "Bob") aliceAndBob --> Dict.fromList [ ( "Bob", 0 ) ]
On peut transformer des éléments avec map.
alice = Dict.fromList [ ( "Alice", 0 ) ]
empty = Dict.map (\player count -> count + 1) alice --> Dict.fromList [ ( "Alice", 1 ) ]
On peut combiner ou transformer des dictionnaires avec merge.
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 ) ]
Toute fonction ou tout opérateur qui semble modifier un dictionnaire (par exemple en ajoutant un élément) renvoie en réalité un nouveau dictionnaire. Les performances ne posent généralement pas de problème, car l'implémentation évite les allocations et les copies inutiles.
En Elm, il est généralement préférable d'utiliser des abstractions de plus haut niveau, comme Dict.map, Dict.filter et Dict.merge, plutôt que des abstractions de plus bas niveau comme Dict.get et Dict.remove, même si cela dépend bien sûr du contexte.
Ta tâche consiste à prendre une liste de buteurs d'un match et à compter combien de buts chaque joueur a marqués.
PlayerName est un alias de type pour String, pour rendre le code plus facile à lire et pour distinguer cet usage de String d'autres usages de String.
Implémente d'abord updateGoalCountForPlayer pour initialiser ou incrémenter le nombre de buts d'un joueur.
Implémente ensuite la fonction aggregateScorers pour compter combien de buts chaque joueur a marqués, en utilisant updateGoalCountForPlayer.
Cette fonction prend une List PlayerName (les noms des joueurs qui ont marqué les buts, qui peut contenir des noms de joueurs en double), et renvoie un Dict PlayerName Int contenant tous les joueurs de la liste ainsi que le nombre de buts qu'ils ont marqués.
aggregateScorers [ "Betty", "Cedd", "Betty" ]
--> Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ]
Implémente la fonction removeInsignificantPlayers, pour filtrer les joueurs qui ont marqué moins de buts que le seuil.
removeInsignificantPlayers 2 (Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ] )
--> Dict.fromList [ ( "Betty", 2 ) ]
Implémente la fonction resetPlayerGoalCount pour remettre à zéro le nombre de buts marqués par un joueur.
resetPlayerGoalCount "Cedd" (Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ] )
--> Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 0 ) ]
Implémente la fonction formatPlayer pour formater le nombre de buts d'un joueur sous forme de string. Si le joueur n'existe pas dans le dictionnaire, considère que son nombre de buts est zéro.
formatPlayer "Betty" (Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ] )
--> "Betty: 2"
Implémente la fonction formatPlayers pour formater le nombre de buts de tous les joueurs sous forme de string. Les joueurs doivent être triés par nom de joueur.
formatPlayers (Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ] )
--> "Betty: 2, Cedd: 1"
Implémente la fonction combineGames, en comptant le nombre total de buts marqués par chaque joueur dans les deux matchs.
combine Games
(Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ] )
(Dict.fromList [ ( "Betty", 2 ), ( "Mario", 3 ) ] )
--> Dict.fromList [ ( "Betty", 4 ), ( "Cedd", 1 ), ( "Mario", 3 ) ]
Inscris-toi sur Exercism pour apprendre et maîtriser Elm avec 28 concepts110 exercices, et un vrai mentorat humain, le tout gratuitement.