Nella scorsa lezione abbiamo iniziato a parlare dei cicli introducendo l’utilizzo del ciclo for. In questa lezione parleremo del ciclo while e l’utilizzo dello switch.
Ciclo While e Repeat-While
I suddetti cicli si comportano come il ciclo for unica differenza è quando si utilizza il repeat
// Solo con while while <condizione> { <istruzioni> } // Esempio var indice = 0 while indice < 10 { // finché i è < 10 esegui il ciclo print(indice) indice += 1 //oppure indice = indice +1 } // Con Repeat repeat { <istruzionii> } while <condizione> var indice = 0 repeat { indice += 1 // oppure indice = indice +1 print(indice) } while indice < 10
La differenza tra le 2 forme è nella esecuzione del codice ovvero Il ciclo while controlla prima che la condizione sia verificata poi esegue il codice mentre nel ciclo repeat-while la condizione di verifica si trova alla fine, quindi prima esegue sempre un ciclo di istruzione e poi ne verifica la condizione.
Istruzione Switch
Lo switch puoi considerarlo come l’istruzione if else. La sua caratteristica è quella di controllare lo stato di un valore e creare dei particolari blocchi di codice che si attivano solo se quel valore corrisponde al particolare caso.
switch valore_da_controllare { case valore_1: eseguo codice del valore_1 case valore_2, valore_3: eseguo codice del valore_2 e 3 default: in caso contrario fai qualcos'altro }
Come vedi il codice inizia con la parola chiave switch seguita dalla variabile da controllare, subito sotto vengono inserite le possibili soluzioni precedute dalla parola chiave case e in fine inserita la parola default con eventuale codice da eseguire in caso il dato da controllare non rietri in nessun case. Il blocco default è sempre obbligatorio.
Attenzione! Un case non esegue operazioni logiche. Esempio case <10. Ogni case deve avere almento un istruzione.
Ecco alcuni esempi
// Esempi // Dato preciso let Carattere = "e" // Dato da controllare switch Carattere { case "a", "e", "i", "o", "u": print("\(Carattere) è una vocale") case "b", "c", "d", "f", "g", "h", "l", "m", "n", "p", "q", "r", "s", "t", "v", "z": print("\(Carattere) è una consonante") default: print("\(Carattere) non è né una vocale né una consonante") } // Dato in range var VotoAlunno = 7 // Voto switch VotoAlunno { case 0...5: print("Voto Insufficiente") case 6...9: print("Voto Buono") case 10: print("Voto Ottimo!") default: print("valore non consentito max 10 e min 0") }
Nel primo esempio il dato da controllare è il valore della costate Carattere, nel primo case verifica se il valore è una vocale, se si stampa “è un vocale”, nel secondo case controlla se è una constante, se si stampa “è una consonante”, se invece il valore non è ne una constante ne una vocale esegue il codice presente in default è stampa “non è un né una vocale né una consonante”.
Nel Secondo esempio utilizziamo un rage di intervalli di valore per determinare il voto di un alunno, il valore è dato dalla variabile VotoAlunno, se il Suo valore è compreso tra 0 e 5 stampa “Voto insufficiente”, tra 6 e 9 stampa “Voto buono”, 10 stampa “Voto Ottimo” altrimente esegue il codice di default stampando un avviso “valore non consentito max 10 e min 0”.
Break, continue, fallthrough e return
Come avrai capito il codice viene eseguito a cascata partendo dalla riga 1 fino alla riga x. Esistono delle parole chiave che alterano il normale svolgimento a cascata, permettendo di saltare da un blocco di codice ad un altro.
Si chiamano break, continue, fallthrough e return. Le prime 3 te le spiegherò in questa lezione mentre l’ultima nella lezione sulle funzioni.
Le prime 3 parole chiave ti consento di continuare, bloccare o eseguire in codice subito sotto.
Ogni istruzione impega nel tempo per essere eseguita e quando il codice comincia a diventare corposo e i dati da controlla sono tanti gazie al giusto utilizzo di queste parole chiave sarà possibile risparmiare tempo che in pratica si traduce in velocità o ottimizzazione della tua applicazione.
Immagina che una stringa sia lunga centinaia e centinaia di elementi (ancora peggio se è un array o dizionario), il tuo compito è quello di scovare un elemento. Senza l’utilizzo di queste parole chiave dovresti scorrere l’intera stringa anche quando l’elemento è stato trovato quindi uno sprego di tempo.
Continue
come dice la parola stessa utilizzando questa parola chiave comunichi al compilatore di andare avanti con l’esecuzione del prossimo ciclo.
Vediamo un esempio, metti che voglia da una frase ricavare una nuova stringa contenente solo le consonanti di quella frase.
let stringa = "questa la mia frase da controllare" var nuovaStringa = "" for carattere in stringa { switch carattere { case "a", "e", "i", "o", "u", " ": continue // se trova una vocale o spazio va avanti al prossimo carattere //(quindi al prossimo ciclo) default: // se non è una vocale o uno spazio inserisce il carattere // nella nuova stringa nuovaStringa.append(carattere) } } print(nuovaStringa)
In pratica: stringa è la frase da controllare mentre nuovaStringa è la variabile che conterrà la nuova frase formata solo dalle consonanti della frase che sarà creata tramite lo scorrimento della intera frase tramite un ciclo for e utilizzo di uno switch.
Quando inizia il ciclo viene preso il primo carattere della frase poi lo switch controlla se è una vocale o uno spazio, se si esegue l’istruzione continue quindi passa al prossimo carattere ovvero ricominicia il ciclo ( come detto ogni case vuole almento un istruzione, con continue gli dico ok continua), quando il carattere non è una vocale o uno spazio esegue il default che non fa altro che aggiungere tramite il comando .append il carattere nella variabile nuovaStringa. Finito tutto il ciclo avrò la variabile nuovaStringa composta da una frase di sole consonanti.
Break
Con l’utilizzo di questa parola chiave posso bloccare immediatamente l’esecuzione di un blocco di codice.
Vediamo un esempio, metti che da una stringa lunga formata 20 caratteri di 0 e e da un solo 1, io voglia sapere dopo quanti 0 sia presente l’uno.
// Per comodità ho creato una striga di solo 20 caratteri var stringa = "00000001000000000000" var i = 0 // contatore for valore in stringa { if (valore == "1") { print("trovato 1") break } i += 1 } print("il valore 1 si trova dopo il \(i)° 0")
In pratica: stringa è formata da 20 caratteri ma potrebbero essere 1.000, 10.000 ecc ecc ed è la seguenza da controllare mentre “i” è la variabile che utilizzerò come contatore che sarà incrementata ad ogni fine ciclo fino a quando non troverà il valore 1.
Quando il ciclo inizia viene preso il primo carattere, se uguale a 0 incrementa di uno il valore di “i” quando invece trova il valore 1 tramite l’istruzione break gli dico ok! ho trovato quello che cercavo poi uscire dal ciclo e stampare il risultato.
Se non avrei utilizzato la parola chiave break avrei dovuto memorizzare il valore di “i” quando trovato il valore 1 e avrei continuato a scorrere anche il resto della striga dopo il valore 1 quindi avrei effettuato cicli in più anche se non necessari.
Utilizzando il break il compilatore ha eseguito solo 7 cicli perchè il valore 1 si trova in ottava posizione mentre senza il suo utilizzo il compilatore avrebbe effettuato 20 cicli prima di uscire.
E se la stringa forse composta da 10.000 elementi e il valore zero si trovasse nella possizione 100? Con il break si risparmiano 9.900 cicli che si traducono in ottimizzazione del codice e velocità :-).
Fallthrough
Tramite questa istruzione possiamo dire in uno switch se esegui questo case allora esegui anche quello successivo.
Vediamo un esempio, metti voglia stampare se una persona faccia solo parte di uno Staff o sia anche il capo oppure nessuno dei 2, potrei utilizzare questa parola chiave in uno swith.
let nome = "francesco" var frase = "\(nome) è " switch nome{ case "francesco" : frase += "il capo ed è " fallthrough case "luca", "mario", "giovanni": frase += "un membro dello Staff" default: frase = "\(nome) Non fa parte dello Staff" } print (frase)
In pratica: nome è la variabile che contiene il nome da controllare mentre “frase” è la variabile che stamperò alla fine contenente inizialmente il valore “nome è” e che cambierà in base al case.
Nel caso il nome sia “francesco” gli ho detto aggiungi alla frase tramite += “il capo ed è ” e con la parola chiave fallthrough gli ho detto esegui anche il codice dello case successivo quindi aggiungi alla frase anche sempre tramite += “un membro dello staff”.
Nel caso sia “luca”, “mario” o “giovanni” aggiungi alla frase iniziale tramite += “un membro dello Staff”.
Tutti gli altri casi gli ho detto azzera la variabile frase tra il solo = e sostiuiscila con “nome non fa parte dello staff”.
Il risultato a stampa sarà:
Se francesco >> francesco è il capo ed è un membro dello Staff
Se luca, mario o giovanni >> luca, mario o giovanni è un membro dello Staff
Se nessuno di loro per esempio carlo allora stamperà carlo non fa parte dello Staff
Per qualunque dubbio o domanda scrivi un commento in questa lezione.
Salve a tutti,
nell’esempio della funzione “break” il playground mi da un errore: “type string does not conformto protocol sequence”. L’ho sistemato aggiungendo “.characters! Quindi:
var stringa = “00000010000000000000”
var 1 = 0 // contatore
for valore in stringa.characters {
if (valore == “1”) {
print(“trovato 1”)
break
}
i += 1
}
print(“il valore 1 si trova dopo il \(i)° 0”)
Solo per la cronaca e perchè mi dava errore, magari è capitato anche a qualcun’alrtro!
Ciao,
la nuova versione di swift ha eliminato la necessità di specificare la proprietà .characters quindi devi scrivere:
var stringa = “00000010000000000000”
var 1 = 0 // contatore
for valore in stringa {
if (valore == “1”) {
print(“trovato 1”)
break
}
i += 1
}
print(“il valore 1 si trova dopo il \(i)° 0”)