Gli intervalli rappresentano l'insieme dei valori compresi tra due estremi.
I tipi più comuni che supportano gli intervalli sono Int, Char e String.
Si possono usare per molte cose, come creare rapidamente una collezione, estrarre sottostringhe, controllare se un valore è compreso in un intervallo e iterare.
Si creano con l'operatore di intervallo .. o ... (rispettivamente inclusivo ed esclusivo).
1..5 # A range containing 1, 2, 3, 4, 5
1...5 # A range containing 1, 2, 3, 4
Il motivo per cui esistono due operatori di intervallo è poter creare intervalli che includono o escludono il valore finale: una cosa utile, per esempio, quando si lavora con indici che partono da zero.
Gli intervalli si possono anche creare usando l'inizializzatore Range.
Range.new(1, 5) # A range containing 1, 2, 3, 4, 5
Quando crei un intervallo in Crystal con gli operatori .. o ... e vuoi chiamare un metodo su quell'intervallo, devi racchiuderlo tra parentesi.
Altrimenti il metodo verrà chiamato sul secondo argomento dell'operatore di intervallo.
(1..5).size # => 5
1..5.size # => Error: undefined method 'size' for Int32
Quando vuoi estrarre una parte di una stringa, puoi usare l'operatore di intervallo per ottenere una sottostringa. Basta creare un intervallo con l'indice iniziale e quello finale della sottostringa.
"Hello World"[0..4] # => "Hello"
"Hello World"[6..10] # => "World"
Puoi anche usare indici negativi per ottenere la sottostringa dalla fine della stringa.
"Hello World"[-5..-1] # => "World"
"Hello World"[6..-4] # => "Wo"
Gli intervalli hanno una serie di metodi con cui lavorare. Per esempio, questi metodi permettono di ottenere la somma di tutti i valori dell'intervallo o di verificare se l'intervallo include un valore.
| Metodo | Descrizione | Esempio |
|---|---|---|
sum |
Restituisce la somma di tutti i valori dell'intervallo | (1..5).sum # => 15 |
size |
Restituisce la dimensione dell'intervallo | (1..5).size # => 5 |
includes? |
Restituisce true se l'intervallo include il valore dato, altrimenti false
|
(1..5).includes?(3) # => true |
Un intervallo può essere senza fine e senza inizio.
In un intervallo senza fine o senza inizio il valore iniziale o quello finale è nil, ma nil può essere omesso quando si definisce l'intervallo.
Usare intervalli senza inizio e senza fine è utile quando vuoi, per esempio, estrarre una parte di stringa dall'inizio o fino alla fine.
"Hello World"[0..] # => "Hello World"
"Hello World"[4..] # => "o World"
"Hello World"[..5] # => "Hello"
Se non viene usato su una collezione, un intervallo senza fine può generare una sequenza infinita, se non lo si usa con cautela.
I caratteri si possono usare negli intervalli e permettono di ottenere un intervallo di caratteri compreso tra due caratteri. Per esempio, può essere comodo quando vuoi ottenere l'alfabeto.
'a'..'z' # A range containing ['a', 'b', 'c', ..., 'z']
Anche le stringhe si possono usare negli intervalli, il che permette di ottenere un intervallo di stringhe tra due stringhe.
Il comportamento però è un po' diverso da quello di Char quando in un intervallo di stringhe si usano più caratteri.
Con gli intervalli di stringhe più complessi il comportamento può diventare confuso, quindi fai attenzione.
("aa".."az") # A range containing ["aa", "ab", "ac", ..., "az"]
Da appassionato di scacchi, vuoi scrivere la tua versione del gioco. Certo, online ci sono già tantissime implementazioni degli scacchi, ma la tua sarà unica!
Inizi implementando un sistema di movimento di base per i pezzi.
La partita di scacchi si giocherà su una scacchiera di otto caselle di larghezza e otto caselle di lunghezza. Le caselle sono identificate da una lettera e da un numero.
Il gioco dovrà memorizzare le traverse della scacchiera. Le traverse sono le righe della scacchiera e sono numerate da 1 a 8.
Il gioco dovrà anche memorizzare le colonne della scacchiera. Le colonne sono disposte in verticale e sono identificate dalle lettere dalla A alla H.
Definisci le costanti Chess::RANKS e Chess::FILES, che memorizzano rispettivamente l'intervallo delle traverse e quello delle colonne.
Chess::RANKS
# => 1..8
Chess::FILES
# => 'A'..'H'
Il gioco dovrà verificare se una casella è valida. Una casella è valida se la traversa e la colonna rientrano negli intervalli delle traverse e delle colonne.
Definisci il metodo Chess.valid_square?, che prende gli argomenti rank, che contiene un numero intero che rappresenta la traversa, e file, che contiene un carattere che rappresenta la colonna.
Il metodo deve restituire true se la traversa e la colonna rientrano nell'intervallo delle traverse e delle colonne, e false in caso contrario.
Chess.valid_square?(1, 'A')
# => true
Il gioco dovrà ottenere il soprannome del giocatore. Il soprannome è formato dai primi due caratteri del nome del giocatore e dagli ultimi due caratteri del suo cognome. Il soprannome deve essere scritto in maiuscolo.
Definisci il metodo Chess.nickname, che prende gli argomenti first_name, che contiene una stringa con il nome del giocatore, e last_name, che contiene una stringa con il cognome del giocatore.
Il metodo deve restituire il soprannome del giocatore come stringa in maiuscolo.
Chess.nickname("John", "Doe")
# => "JOOE"
Il gioco dovrà creare un messaggio per una mossa, per indicare quale giocatore si è spostato su quale casella. Il messaggio deve usare il soprannome del giocatore e la casella su cui si è spostato. Il gioco deve anche determinare se la mossa è valida, verificando se la colonna e la traversa della casella rientrano negli intervalli delle colonne e delle traverse.
Se la mossa è valida, il messaggio deve essere: "{nickname} moved to {square}"
Se la mossa non è valida, il messaggio deve essere: "{nickname} attempted to move to {square}, but that is not a valid square"
Definisci il metodo Chess.move_message, che prende gli argomenti first_name, che contiene una stringa con il nome del giocatore, last_name, che contiene una stringa con il cognome del giocatore, e square, che contiene una stringa con la casella su cui il giocatore si è spostato.
Il metodo deve restituire il messaggio della mossa come stringa.
Chess.move_message("John", "Doe", "A1")
# => "JOOE moved to A1"
Iscriviti a Exercism per imparare e padroneggiare Crystal con 26 concetti142 esercizi e il mentoring di persone reali, tutto gratis.