# Lezione 2 - [Array](#array) - [Metodi e proprietà degli array](#metodi-e-proprieta-degli-array) - [Istruzioni condizionali, if e switch.](#istruzioni-condizionali-if-e-switch) - [I cilci for e while](#i-cilci-for-e-while) ---   # Array L'array è un oggetto usato per associare più valori in una singola variabile: ```js var generiMusicali = ["pop", "rock", "punk"]; ``` la scrittura equivalente, usando singole variabili potrebbe essere questa: ```js var genere1 = "pop"; var genere2 = "rock"; var genere3 = "punk"; ``` che può anche andare bene per pochi elementi, ma che succede se di generi musicali ne abbiamo 1000 invece di 3? La soluzione è l'array, che ci consente di inserire tutti i valori che vogliamo in una singola variabile. Possiamo accedere ai singoli elementi dell'array riferendoci al suo **indice numerico**, ricordandoci che parte sempre da zero! ## Creazione di un array Il metodo più immediato è quello di definire un array basato sulla *rappresentazione letterale*: ```js var nome_array = [elemento1, elemento2, ... ]; /* Possiamo rappresentare un array su più righe se questo può migliorare la leggibilità del nostro codice */ var generiMusicali = [ "pop", "rock", "punk" ]; /* Possiamo creare un array anche con il metodo new Array(), ma è meno intuitivo e considerato una cattiva pratica. */ var generiMusicali = new Array("pop", "rock", "punk"); ``` come possiamo notare si tratta semplicemente di un elenco di elementi separati da una virgola e dentro delle parentesi quadre. > se dobbiamo fare un array di numeri è importante ricordare le regole sui tipi di dato JavaScript, in quel caso non dobbiamo usare apici di nessun tipo (es: `var numeriAcaso = [4,8,15,16,23,42]`), altrimenti i numeri verrebbero comunque interpretati come una stringa! ## Accedere agli elementi di un array Come abbiamo detto prima, gli array sono dotati di un indice numerico che parte da zero ([0] per il primo elemento, [1] per il secondo elemento e così via), ne consegue che per accedere al **primo elemento** del nostro array dobbiamo scrivere: ```js var generePrescelto = generiMusicali[0]; // pop ``` allo stesso modo possiamo **modificare** gli elementi dell'array: ```js // modifichiamo il primo generiMusicali[0] = "folk"; // modifichiamo il terzo generiMusicali[2] = "metal"; /* l'array sarà quindi diventato: ["folk", "rock", "metal"]; ```   # Metodi e proprietà degli array la vera forza degli array sono le sue proprietà e i suoi metodi nativi. ## Proprietà **length** La proprietà length ci restituisce il numero degli elementi che compongono l'array. ```js var generiMusicali = ["pop", "rock", "punk"]; generiMusicali.length; // 3 ``` `length` è sempre una unità in più rispetto al numero più alto dell'indice dell'array, qundi possiamo ad esempio trovare l'ultimo elemento di un array facendo: ```js var ultimo = generiMusicali[generiMusicali.length - 1] // punk ``` ## Il metodo **push()** La maniera più semplice di aggiungere un elemento alla fine del nostro array è quella di usare il metodo push: ```js var generiMusicali = ["pop", "rock", "punk"]; generiMusicali.push("blues"); // ["pop", "rock", "punk", "blues"] /* per aggiungere un elemento alla fine dell'array possiamo usare anche la proprietà length */ generiMusicali[generiMusicali.length] = "blues"; // o usare direttamente il numero di indice: generiMusicali[3] = "blues"; // facendo però attenzione a non generare buchi! generiMusicali[4] = "blues"; // ["pop", "rock", "punk", undefined, "blues"] ``` ## Il metodo **pop()** Questo metodo rimuove l'ultimo elemento da un array: ```js var generiMusicali = ["pop", "rock", "punk"]; var genereTolto = generiMusicali.pop(); // punk /* l'array diventa ["pop", "rock"] nella variabile genereTolto viene salvato l'elemento eliminato */ ``` ## Il metodo **shift()** `shift()` è equivalente a `pop()` con la differenza che lavora sul primo elemento dell'array invece che sull'ultimo, l'indice dell'array viene fatto slittare: ```js var generiMusicali = ["pop", "rock", "punk"]; var genereTolto = generiMusicali.shift(); // pop /* l'array diventa ["rock", "punk"] nella variabile genereTolto viene salvato l'elemento eliminato adesso l'indice riparte da "rock" */ /* oltre a shift e pop potremmo usare anche delete per eliminare un elemento, ma è una cattiva pratica perché lascia dei buchi */ delete generiMusicali[0]; // [undefined, "rock", "punk"] ``` ## Il metodo **splice()** Con questo metodo possiamo aggiungere o togliere elementi in qualsiasi posizione dell'array. Prevede due argomenti obbligatori e un numero indefinito di argomenti opzionali e ci restituisce gli elementi rimossi. ``` array.splice(indice, quantiNeTolgo, elemento1, elemento2, ...); | obbligatori | opzionali | ``` ESEMPIO: ```js var generiMusicali = ["pop", "rock", "punk", "blues"]; var genereTolto = generiMusicali.splice(1,2); // "rock", "punk" /* l'array diventa ["pop", "blues"] nella variabile genereTolto vengono salvati gli elementi eliminati */ // inseriamo bossa nova e techno prima di pop generiMusicali.splice(0,0, "bossa nova", "techno"); ``` ## Il metodo **unshift()** Questo metodo aggiunge un nuovo elemento all'inizio dell'array, facendo scorrere nell'indice gli altri elementi: ```js var generiMusicali = ["pop", "rock", "punk"]; generiMusicali.unshift("blues"); // 4 /* l'array diventa ["blues", "pop", "rock", "punk"] adesso l'indice riparte da "blues" che sara [0], pop [1] e così via fino alla fine dell'array. restituisce come output la nuova lunghezza 4 */ ``` ## Il metodo **concat()** Con questo metodo possiamo unire 2 o più array. Questo metodo non va a cambiare l'array originale, ne crea uno nuovo. ``` array1.concat(array2, array3, array4, ...); ``` ESEMPIO: ```js var generiMusicali = ["pop", "rock", "punk"]; var altriGeneriMusicali = ["jazz", "blues"]; var generiUniti = generiMusicali.concat(altriGeneriMusicali); // generiUniti = ["pop", "rock", "punk", "jazz", "blues"] ``` ## Ordiniamo gli array di stringhe con sort() il metodo sort() ordina gli elementi dell'array alfabeticamente, pertanto produce risultati errati con i numeri. ```js var generiMusicali = ["pop", "rock", "punk", "blues"]; var arrayRiordinato = generiMusicali.sort(); // ["blues", "pop", "punk", "rock"] ``` ## Convertiamo un array in una stringa: i metodi **toString()** e **join()** ### toString() questo metodo converte l'array in una stringa con gli elementi separati da una virgola: ```js var generiMusicali = ["pop", "rock", "punk", "blues"]; generiMusicali.toString(); // pop,rock,punk,blues ``` ### join() anche questo metodo converte l'array in una stringa, solo che possiamo decidere come separarli: ```js var generiMusicali = ["pop", "rock", "punk", "blues"]; // un trattino tra due spazi generiMusicali.join(" - "); // pop - rock - punk - blues // o una virgola e spazio generiMusicali.join(", "); // pop, rock, punk, blues // o quello che vogliamo generiMusicali.join("_"); // pop_rock_punk_blues ``` > Quelli descritti in questo capitolo sono solo alcuni dei metodi degli array che JavaScript ci mette a disposizione, altri verranno trattati nelle prossime lezioni.   # Istruzioni condizionali, `if` e `switch` Prima di partire è opportuno definire un **blocco di codice**, che è un insieme di istruzioni racchiuso tra parentesi graffe: ```js { var pippo = 10; var topolino = pippo / 2 + 3; } console.log(topolino); // 8 ``` Alla fine di un blocco di codice non abbiamo bisogno di inserire il `;`. Le **istruzioni condizionali** ci permettono di eseguire *blocchi di codice* a seconda di una condizione stabilita. ## istruzione **if** Possiamo trovarla in tre forme: - semplice - con alternativa `if else` - a cascata `if else if else` ```js // semplice if (condizione) { // se la condizione è vera // istruzioni } // con alternativa if (condizione) { // se la condizione è vera // istruzioni } else { // altrimenti // istruzioni alternative } // a cascata if (condizione) { // istruzioni 1 } else if (altra_condizione) { // istruzioni 2 } else { // altrimenti // istruzioni 3 } ``` ESEMPIO: ```js var anni = 21; if (anni < 18) { messaggio = "Non può votare"; } else if (anni >= 18 && anni < 25 ) { messaggio = "Può votare solo alla Camera"; } else { messaggio = "Può votare alla Camera e al senato"; } // possiamo anche annidare le istruzioni if (anni < 18) { messaggio = "Non può votare"; } else { if(anni < 25) { messaggio = "Può votare solo alla Camera"; } else { messaggio = "Può votare alla Camera e al senato"; } } // entrambe le versioni sono valide, la prima è più elegante. ``` ## Istruzione `switch` A volte le alternative da proporre sono tante e un `if` a cascata potrebbe essere poco pratico. In questo caso ci viene in aiuto `switch`: ```js switch (espressione) { case espressione1: istruzioni1; break; case espressione2: istruzioni2; break; // altre istruzioni default: istruzioni4; break; } ``` L'espressione principale di switch viene confrontata con i vari case, quando viene individuata restituisce le istruzioni corrispondenti, altrimenti esegue il `default`. L'istruzione `break` è importante e dice allo switch di fermarsi. ESEMPIO: ```js switch(razza) { case "Jack Russell": case "Chihuahua": case "Beagle": messaggio = "Cacacazzi"; break; case: "Carlino": messaggio = "Respira male"; break; case: "Alano": messaggio = "Grosso ma tranquillo"; break; default: messaggio = "Non sono stato istruito per questa razza"; break; } /// i primi 3 case restituiscono tutti la stessa istruzione, non essendo interrotti da un break. ```   # I cilci for e while A volte può essere necessario ripetere una serie di istruzioni diverse volte, o fino al verificarsi di una determinata condizione. In queste circostanze ricorreremo ai **cicli**, anche chiamati *iterazioni*. JavaScript supporta diverse tipologie di iterazioni: - for - while - do while ## Ciclo **for()** Con questa istruzione possiamo eseguire un blocco di codice un numero determinato di volte. Per definirlo abbiamo bisogno di: 1. una variabile *contatore* a cui assegnamo un numero di partenza (di solito lo 0) 2. una *condizione* di terminazione (il valore della variabile contatore che una volta raggiunta termina il ciclo) 3. uno *step*, cioè l'incremento o il decremento da applicare alla variabile contatore ```js for (contatore; condizione; step) { // istruzioni } ``` ESEMPIO: ```js // Contiamo da 0 a 100 var i; for(i=0; i<=100; i++) { console.log(i); } ``` Nell'esempio abbiamo la variabile `i` che usiamo come contatore, una condizione che termina il ciclo quando `i` `<=` (minore o uguale di) `100` e lo step `i++` (equivalente a `i = i+1`). ## Ciclo **while()** Questo ciclo, a differenza del `for()` non prevede un contatore, ma semplicemente una condizione di terminazione: ```js while (condizione) { istruzioni; } ``` Nell'esempio che segue proviamo a rifare il contatore fatto prima con `for()`: ```js var i = 0; while (i<=100) { console.log(i); i++; // lo step lo indichiamo dentro il blocco di istruzioni! } ``` > Nota bene: dobbiamo comunque impostare lo step, altrimenti possiamo imbatterci in un ciclo infinito. Prova ad esempio a lanciare il codice senza l'istruzione `i++`. Anzi, no, se non vuoi bloccare il tuo browser non provarci :) ## Ciclo **do while()** È una variante del `while()` in cui il controllo della condizione viene dopo l'esecuzione dell'istruzione. Quindi l'istruzione viene eseguita sempre almeno una volta. ```js do { istruzioni; } while (condizione); ``` Proviamo anche in questo caso a contare da 0 a 100: ```js var i = 0; do { console.log(i); i++; // lo step per evitare un loop infinito; } while(i<=100); ``` ## I comandi `break` e `continue` ## **break** Lo abbiamo già visto nello `switch()`, in un modo simile lo possiamo utilizzare nei nostri cicli: ```js var i; for(i=0; i<=100; i++) { if(i == 42) { // se raggiungi il 42 console.log("la risposta alla domanda fondamentale sulla vita, l'universo e tutto quanto!") break; // fermati qui } console.log(i); } ``` In pratica possiamo interrompere il ciclo arbitrariamente. ## **continue** Il comando `continue;` interrompe una singola iterazione. Proviamo a bloccare tutti i numeri dispari fino a 100: ```js var i; for(i=0; i<=100; i++) { if(i%2 == 0) { /* Qui usiamo l'operatore % o modulo, in pratica serve per conoscere il resto di una divisione intera. es: 15 / 2 = 7,5 ci interessa solo l'intero, 7 ne consegue che: 15 - (7 * 2) = 1, quindi 15%2 = 1 */ continue; } console.log(i); } ```   # Esercizio 2 Paprika e Ginger sono cagnoline molto veloci. Un giorno decidiamo di fare una gara: le posizioniamo ai blocchi di partenza e gli facciamo fare diversi giri dell'acropoli ottenendo questi tempi: - Paprika: 122, 93, 111 e 80 secondi; - Ginger: 120, 80 e 145 secondi; Stabiliamo che **vogliamo scartare i tempi superiori ai 120 secondi** e consideriamo valida la corsa anche se Ginger si è stancata e non ha corso il quarto giro. Vogliamo sapere: 1. chi ha la media migliore; 2. chi ha corso il giro più veloce. Dovrai inoltre considerare anche i pareggi! ## I passaggi che dovrai eseguire sono i seguenti: 1. crea due *variabili* che contengono gli *array* con i tempi; 2. fai un ciclo *while* per ogni cane, con il quale eliminerai dagli array creati in precedenza, i valori dei tempi superiori ai 120 secondi; 3. fai un ciclo *for* per ogni array dei tempi, nel quale calcolerai il tempo totale e scoprirai il tempo migliore; 4. crea due variabili dove calcolerai la media dei tempi a seconda del cane; 5. decreta il vincitore per media; 6. decreta il vincitore per tempi. E occhio ai pareggi! ## Suggerimenti: - Probabilmente non è necessario dirlo ma la **media** si calcola sommando i valori e dividendo per il numero di valori es: media tra 4, 5 e 9 => (4 + 5 + 9) / 3 = 6 - Occhio ai loop infiniti nei **cicli**. - Usa tutte le variabili che ritieni necessarie, avrai anche bisogno degli operatori relazionali e logici, soprattutto all'interno delle istruzioni `if`.