Track
/
Elm
Elm
/
Esercizi
/
I migliori marcatori
I migliori marcatori

I migliori marcatori

Esercizio di apprendimento

Introduzione

Dict

Un Dict in Elm è un dizionario immutabile di zero o più coppie chiave-valore.

I Dict si manipolano tramite funzioni e operatori definiti nel modulo Dict.

Le annotazioni di tipo per i Dict si scrivono come segue

Dict String (List Int) --> a dict with String keys and List Int values
Dict Int String --> a dict with Int keys and String values

I Dict si possono creare così:

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

Gli elementi si possono recuperare con get. Dato che una chiave può essere presente o meno nel dict, il risultato sarà racchiuso in un Maybe.

alice = Dict.fromList [ ( 0, "Alice" ) ]
keyExists = Dict.get 0 alice --> Just "Alice"
keyNotPresent = Dict.get 1 alice --> Nothing

Gli elementi si possono aggiungere con insert. Gli elementi con chiavi già presenti nel dict vengono sostituiti.

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 ) ]

Gli elementi si possono aggiornare con update. Se la chiave non esiste, la funzione di aggiornamento verrà chiamata con 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" ) ]

Gli elementi si possono rimuovere con remove. Se la chiave non esiste, non viene apportata alcuna modifica.

alice = Dict.fromList [ ( 0, "Alice" ) ]
stillAlice = Dict.remove 1 --> ( 0, "Alice" )
empty = Dict.remove 0 alice --> Dict.empty

Una lista di coppie chiave-valore si può convertire in un dict con fromList.

alice = Dict.fromList [ ( 0, "Bob" ), ( 0, "Alice" ) ]
--> True Dict.fromList [ ( 0, "Alice" ) ]

Gli elementi si possono convertire in una lista con toList. La lista è ordinata in base alle chiavi.

aliceAndBob = Dict.fromList [ ( 1, "Alice" ), ( 0, "Bob" ) ]
bobAndAlice = Dict.toList aliceAndBob
--> [ ( 0, "Bob" ), ( 1, "Alice" ) ]

Più elementi si possono rimuovere con filter.

aliceAndBob = Dict.fromList [ ( "Alice", 1 ), ( "Bob", 0 ) ]
bob = Dict.filter (\name count -> name == "Bob") aliceAndBob --> Dict.fromList [ ( "Bob", 0 ) ]

Gli elementi si possono trasformare con map.

alice = Dict.fromList [ ( "Alice", 0 ) ]
empty = Dict.map (\player count -> count + 1) alice --> Dict.fromList [ ( "Alice", 1 ) ]

I Dict si possono combinare / trasformare con 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 ) ]

Qualsiasi funzione o operatore che sembra modificare un dict (per esempio aggiungendo un elemento) in realtà restituisce un nuovo dict. Le prestazioni di solito non sono un problema, perché l'implementazione evita allocazioni e copie superflue.

In Elm, in genere è meglio usare astrazioni di livello più alto, come Dict.map, Dict.filter e Dict.merge, invece di astrazioni di livello più basso come Dict.get e Dict.remove, anche se naturalmente dipende dal contesto.

Istruzioni

Il tuo compito sarà prendere un array di marcatori di una partita e contare quanti gol ha segnato ogni giocatore.

PlayerName è un alias di tipo per String, per rendere il codice più leggibile e per distinguere questo uso di String da altri usi di String.

1. Aggrega i marcatori

Per prima cosa, implementa updateGoalCountForPlayer per inizializzare o incrementare il conteggio dei gol di un giocatore. Poi implementa la funzione aggregateScorers per contare quanti gol ha segnato ogni giocatore, usando updateGoalCountForPlayer. Questa funzione prende una List PlayerName (i nomi dei giocatori che hanno segnato i gol, che può contenere nomi di giocatori duplicati) e restituisce un Dict PlayerName Int contenente tutti i giocatori dell'array insieme al numero di gol che hanno segnato.

aggregateScorers [ "Betty", "Cedd", "Betty" ]
--> Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ]

2. Rimuovi i giocatori irrilevanti

Implementa la funzione removeInsignificantPlayers per filtrare tutti i giocatori che hanno segnato meno gol della soglia.

removeInsignificantPlayers 2 (Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ] )
--> Dict.fromList [ ( "Betty", 2 ) ]

3. Azzera il conteggio dei gol di un giocatore

Implementa la funzione resetPlayerGoalCount per riportare a zero i gol segnati da un giocatore.

resetPlayerGoalCount "Cedd" (Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ] )
--> Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 0 ) ]

4. Formatta il conteggio dei gol di un singolo giocatore

Implementa la funzione formatPlayer per formattare come stringa il conteggio dei gol di un singolo giocatore. Se il giocatore non esiste nel dict, presumi che il suo conteggio dei gol sia zero.

formatPlayer "Betty" (Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ] )
--> "Betty: 2"

5. Formatta il conteggio dei gol di tutti i giocatori

Implementa la funzione formatPlayers per formattare come stringa il conteggio dei gol di tutti i giocatori. I giocatori devono essere ordinati per nome.

formatPlayers (Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ] )
--> "Betty: 2, Cedd: 1"

6. Combina le partite

Implementa la funzione combineGames, contando il numero totale di gol che ogni giocatore ha segnato in entrambe le partite.

combine Games
  (Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ] )
  (Dict.fromList [ ( "Betty", 2 ), ( "Mario", 3 ) ] )
--> Dict.fromList [ ( "Betty", 4 ), ( "Cedd", 1 ), ( "Mario", 3 ) ]
Modifica tramite GitHub Il link si apre in una nuova finestra o scheda
Elm Exercism

Vuoi iniziare I migliori marcatori?

Iscriviti a Exercism per imparare e padroneggiare Elm con 28 concetti110 esercizi e il mentoring di persone reali, tutto gratis.