Compatibile con Xcode 8

Ciclo for in Swift. Quando ripetere salva la vita dei programmatori

Questa volta non voglio perdermi in chiacchere. Voglio subito subito metterti di fronte a questi famigerati cicli del linguaggio Swift.

Immagina un’applicazione in cui hai bisogno di memorizzare una lista di utenti.

Gli utenti, con le conoscenze apprese fin ora (almeno spero, altrimenti esci subito da questo sito!), sai che possono essere conservati dentro un array o un dizionario. Fin qui niente di strano.

Però, nel caso in cui volessi stampare tutti i nomi degli utenti, dovresti scrivere N righe con un print quanti sono i valori contenuti nell’array.

Una vera noia. Infatti, pur scrivendo print(<qualcosa>), quel qualcosa cambia sempre e non ti permette di poter eseguire dei copia e incolla veloci (I copia/incolla alla cazzum sono considerati reato).

Ciclo for in swift. Perché nascono i cicli in un linguaggio di programmazione

Con le tecniche apprese fin ora, programmare con il linguaggio Swift diventerebbe frustrante per progetti complessi e articolati. Fortunatamente, il linguaggio Swift, come tutti gli altri, permette di compattare tutte queste istruzioni in una manciata di righe.

No, merlino e le sue magie c’entrano poco!

Il sistema prende il nome di ciclo. Il ciclo in Swift è l’operazione in cui, definito un punto di partenza e un punto di fine (per esempio il primo valore dell’array e l’ultimo), vengono eseguiti N step quanti sono gli elementi che intercorrono tra il punto X ed il punto Y. 

Non c’hai capito na mazza? non preoccuparti, neanche io!

La sintassi del ciclo for del linguaggio Swift

Andiamo con ordine. Come funziona un ciclo con il linguaggio Swift?

Nei linguaggi di programmazione in generale, quindi non solo per Swift, un ciclo rappresenta la capacità di ripetere un blocco di istruzioni. In più, un ciclo, può variare lo stato delle variabili del blocco in base a dei particolari criteri che vedremo man mano.

In pseudo codice, potrei razionalizzare un ciclo, in questa maniera:

Cioè, esisterà una parola chiave o keyword che farà in modo di ripetere per n volte (nell’esempio 10) un blocco di codice (nell’esempio, stamperà per 10 volte la scritta “ciao xCoders”).

Se hai capito questo semplice esempio in pseudo codice, trasformarlo con il linguaggio Swift sarà, spero, altrettanto semplice.

La prima tipologia di ciclo, perché nè esistono diversi, si chiama ciclo for-in.

La sintassi è definita:

  1. Dalla parola chiave for.
  2. Seguita dal nome di una variabile chiamata, in gergo, iteratore.
  3. Dalla parola chiave in.
  4. E da un’intervallo di valori.

Più facile a farsi che a dirsi. Questa è la sintassi classica di un ciclo for in Swift:

Puoi leggerla così: per ogni valore, contenuto nell’intervallo, esegui il blocco d’istruzioni. 

Rappresentare un range o intervallo di valori

Facciamo una piccola digressione sui range di numeri in Swift.

Un range è la rappresentazione contratta di un array di Int. Viene definito il primo elemento x e l’ultimo elemento y, tra x e y vengono messi tre puntini (…) che stanno ad indicare che da x a y ci stanno tutti gli interi compresi tra x e y (x<=…<=y) come se fosse un array indicato solo con il valore della testa e della coda.

Quindi il range di numeri che comprende 1 e 10 si scrive così:

Il primo esempio ed il simbolo Underscore

Partiamo dall’esempio più semplice: stampare 10 print con 10 numeri diversi:

Quello che vuoi fare è creare un ciclo che, per ogni valore da 1 a 10, esegua l’istruzione print. Ogni volta, però, cambiando il numero da stampare.

Quindi, se volessi stampare i numeri da uno a dieci ti dovrai avvalere sicuramente del range 1…10.

Proviamo a scrivere un primo ciclo.

Gli elementi che abbiamo, per completare tutta la sintassi del ciclo, sono: la parola chiave for, la in ed il range. Ci manca la variabile o iteratore.

Per il momento, al posto del campo iteratore, puoi inserire il simbolo underscore _ che ti fa omettere questo passaggio:

ciclo-for-in-linguaggio-swift

Come si usa il campo iteratore?

Il campo variabile, o anche detto iteratore, assume, ad ogni ciclo, un valore del range da passare a rassegna. Puoi pensarlo come ad una variabile che ha lo scopo di assumere, ad ogni giro del ciclo, il valore del range successivo al precedente.

L’iteratore, la prima volta che viene eseguito il ciclo, assume il primo valore del range. Nel nostro caso, assumerebbe il valore 1 (dato che il range 1…10 parte dal valore 1).

ciclo-for-in-swift-e-iteratore

Fin quando non vengono eseguite tutte le istruzioni del ciclo, quella variabile iteratore continuerà a mantenere il valore 1 e quindi, quel valore, potrà essere letto all’interno del blocco del ciclo per eseguire delle operazioni (per esempio la stampa). A fine ciclo, l’iteratore passa al valore successivo del range e continuerà così fin quando non termineranno tutti gli elementi del range.

Ciclo for in swift linguaggio

Adesso, 2 cose dovrebbero essere chiare:

  1. Indifferentemente dalla presenza o meno di una variabile, il ciclo, esegue tante volte il blocco d’istruzioni quanti sono gli elementi del range. Se il Range è di 100 elementi, il ciclo verrà eseguito per 100 volte.
  2. La variabile di lettura o iteratore viene inserita solo quando si vuole utilizzare il valore del range, letto dal ciclo, all’interno del blocco d’istruzioni.

Esercizio 1. Stampare i numeri da 4 a 10.

Stampa i numeri che vanno da 4 a 10.

Un errore d’interpretazione

Un’errore comune è quello di pensare che il ciclo for in Swift venga eseguito tutto in una volta. Mi spiego meglio. Quando scrivi nel Playground qualcosa, essa viene subito interpreta ed eseguita. Cioè, se nel tuo Playground scrivi:

Immediatamente vedi sulla console l’esecuzione della print e il messaggio stampato:

tempi-di-esecuzione-codice-swift-1024x108

Quando esegui un ciclo, anche se viene eseguito istantaneamente, non corrisponde come ad un’unica esecuzione in blocco:

apparente-esecuzione-istantanea-di-un-ciclo-for-1024x143

Il problema ricade nel Playground e nei tempi effettivi di esecuzione. Anche se sono dell’ordine del nanosecondo, ogni istruzione impiega del tempo per essere eseguita. 

Per colpa dell’apparente esecuzione istantanea data dal Playgroundsi è propensi a pensare che un ciclo corrisponde ad un’unica istruzione, ma non è così!

Variabili interne ed esterne al ciclo

Ogni blocco d’istruzioni del ciclo devi immaginarlo come ad un qualcosa che viene eseguito ed infine resettato alla fine delle istruzioni presenti. 

Per capire quello che voglio dire, prova a risolvere questo esercizio.

Esercizio 2. Crea una variabile con valore 10 che viene incrementata di una unità per quanti sono i valori presenti in un range. Per esempio, se il range è 1…4. La variabile, a fine ciclo, dovrà avere il valore 14 (perché nel range ci sono 4 numeri, quindi ad ogni numero del range ha sommato +1 al numero).

La tentazione del giovane sviluppatore è quella di scrivere qualcosa del genere:

Riesci a dirmi cos’è che fa questo ciclo? Se non ti arriva l’illuminazione divina, invece di sparare una risposta a caso, prendi il codice ed incollalo nel Playground.

Alla prima esecuzione, il ciclo si trova a leggere l’elemento 1 del range, entra dentro il blocco ed inizializza la variabile numero con il valore 10. Poi gli incrementa il valore di 1 (il simbolo += l’ho spiegato a metà di questa lezione) e stampa il contenuto della var.

Una volta finite tutte le istruzioni del blocco, al solito, controlla se ci sono o no altri elementi nel range da scorrere. Dato che si trova ancora alla posizione 1, ci sono altre 3 unità da scorrere. Il ciclo passa al valore numero 2.

Letto il numero 2 del range, rientra dentro il blocco e qui accade quello che non volevamo accadesse.

Ad ogni ciclo, la variabile numero viene inizializzata nuovamente al valore di 10. Quindi, la variabile numero dimentica tutto quello che è stato fatto nel ciclo precedente.

Come si risolve?

Si può adottare un piccolo stratagemma. Se inizializzi la variabile numero fuori dal ciclo, il suo valore non verrà mai sovrascritto a meno che non ordinato da te:

Dato che la var numero è stata inizializzata prima, ogni blocco la incrementerà sempre di un valore fin quando non avrà finito di passare a rassegna tutti i valori del range.

Array e ciclo for-in

Con il ciclo for in Swift sei in grado di leggere anche gli elementi di un array e di un dizionario in maniera intuitiva e veloce.

Riprendiamo velocemente cos’è un array. Sai, dalla lezione degli array e dizionari in Swift, che ogni elemento è conservato in una sorta di vagone identificato da un indice.

Con il ciclo for ed il linguaggio Swift sei in grado di passare a rassegna tutti i valori dell’array spostandoti da una posizione all’altra del treno proprio come hai visto fare con i range di numeri.

Nel caso degli array, se volessi scorrere i suoi elementi con il ciclo for, ti basterebbe inserire il suo nome dopo la parola chiave in:

Se, nel range, la variabile iterativa leggeva uno ad uno i valori del range, nel vettore, l’iteratore legge i valori dell’array partendo dalla posizione 0.

Quindi, se all’interno del blocco d’istruzioni stampi il valore dell’iteratore, sulla console spunterà il valore di ogni elemento dell’array:

La storia è sempre la stessa:

  1. Al primo giro la variabile vagone legge il contenuto dell’array alla posizione 0.
  2. Entra dentro il blocco d’istruzioni e stampa “linguaggio swift“.
  3. Finito il codice dentro il blocco, controlla se ci sono altri elementi da leggere.
  4. Se ci sono torna alla riga for e la variabile vagone prende il contenuto dell’array in posizione 1. Entra nel blocco e stampa “c”.
  5. Continua così fin quando non ha finito.

Dizionario e ciclo for

Considerata la presenza delle chiavi e dei valori, il ciclo for in Swift, si complica un pochino:

Ogni elemento di un dizionario del linguaggio Swift è composto sempre da due parti: una chiave ed un valore. Per questo motivo il ciclo deve poter leggere entrambe le parti in un unico colpo. Un po’ come se entrassi in un vagone composto da due cabine.

La variabile iteratrice viene definita da una coppia di variabili, racchiuse in parentesi tonde e divise da una virgola: (chiave, valore).

  • La variabile a sinistra della virgola leggerà sempre la chiave.
  • La variabile a destra della virgola leggerà sempre il valore associato alla chiave.

Applichiamolo ad un esempio.

Esercizio 3. Crea un dizionario la cui chiave rappresenta il nome di un dipendente di un’azienda ed il valore il suo salario. Crea un ciclo che stampa il nome ed il salario del dipendente.

dizionari-e-ciclo-for-linguaggio-swift

In alternativa puoi utilizzare una sola variabile iteratrice. La variabile ti permette di accedere sia alla chiave che al valore  e per farlo devi inserire .0 per la chiave e .1 per il valore.

array e dizionari con il ciclo for in swift

Ciclo for in Swift: Esercizi svolti e commentati

Ti consiglio di guardare tutti gli esempi e di riprovare a emularli e modificarli.

Esercizio 4. Visualizzare gli elementi di un array e contemporaneamente stampa il numero di ciclo.


Esercizio 5.
Stampare solo gli elementi pari di un’array.


Esercizio 6.
Calcolo della potenza di un numero

Calcolare la potenza di un numero, ad esempio 3 elevato a 12, sfruttando il ciclo for in e il simbolo underscore:

Considerazioni e Esercizi della lezione

Se hai qualsiasi sorta di problema ti scongiuro di farmelo sapere! Le lezioni successive si basano tutte, e dico tutte, sul concetto dei controlli, blocchi di istruzioni e cicli.

Quindi lascia un commento e ti aiuterò volentieri, in più al commento prova a svolgere il test della lezione (ti ricordo che devi essere registrato per accedervi) così saprai realmente se hai immagazzinato i concetti del ciclo for-in del linguaggio Swift.

Esercizi non svolti

  • Esercizio 7. Se “var punteggi = [ 20, 14, 55, 5, 7, 8, 36]” è un array e “var punteggioFinale” è una variabile, implementa un ciclo che sommi tutti i valori dell’array e salvi il risultato nella variabile punteggioFinale.
  • Esercizio 8. Crea un’istruzione di controllo che, date due variabili intere, stampi su schermo “a è maggiore di b” oppure il contrario.
  • Esercizio 9. Creare due array vuoti di interi e inizializzare il primo con valori a scelta. Copiate gli elementi del primo array tramite un ciclo nel secondo array.
  • Esercizio 10. Crea un ciclo for che, dato un’array di interi, stampa solo i numeri maggiori di 10 dell’array.

Buona Programmazione!

Changelog

  • 13/10/2016 – Aggiunto il changelog. Modifiche del testo e rimozione di alcuni paragrafi del tutorial. Controllata la compatibilità con Xcode 8 ed il linguaggio Swift 3.0.

Torna a: Corso gratuito linguaggio di programmazione Swift > Dai controlli alle funzioni del linguaggio Swift

Start typing and press Enter to search

Array e Dizionari in SwiftWhile e Switch in Swift