Metodi di Ricerca e Ordinamento degli Array in JavaScript
- In JavaScript, possiamo utilizzare i metodi
indexOf
,lastIndexOf
eincludes
per cercare elementi in un array e determinare la loro posizione. - Il metodo
indexOf
restituisce l'indice del primo elemento trovato, mentrelastIndexOf
restituisce l'indice dell'ultimo elemento trovato. - Il metodo
includes
verifica se un array contiene un elemento specifico e restituiscetrue
ofalse
. - I metodi
sort
ereverse
consentono di ordinare gli elementi di un array e di invertirne l'ordine. - Il metodo
sort
ordina gli elementi in ordine alfabetico per impostazione predefinita, ma può essere personalizzato con una funzione di confronto. - Il metodo
reverse
inverte l'ordine degli elementi di un array, modificando l'array originale. - Questi metodi sono utili per la manipolazione e l'ordinamento degli array in JavaScript, facilitando la ricerca e l'organizzazione dei dati.
Metodi di Ricerca e Ordinamento degli Array
Gli array implementano i metodi indexOf()
, lastIndexOf()
, e includes()
che sono simili ai metodi con lo stesso nome delle stringhe.
Ci sono anche i metodi sort()
e reverse()
per riordinare gli elementi di un array.
Vediamo come funzionano questi metodi.
indexOf
e lastIndexOf
indexOf()
e lastIndexOf()
cercano in un array un elemento con un valore specificato e restituiscono l'indice del primo elemento trovato, o -1
se nessuno viene trovato.
indexOf()
cerca nell'array dall'inizio alla fine, e lastIndexOf()
cerca dalla fine all'inizio:
let a = [0,1,2,1,0];
a.indexOf(1) // => 1: a[1] è 1
a.lastIndexOf(1) // => 3: a[3] è 1
a.indexOf(3) // => -1: nessun elemento ha valore 3
indexOf()
e lastIndexOf()
confrontano il loro argomento con gli elementi dell'array utilizzando l'equivalente dell'operatore ===
. Se l'array contiene oggetti invece di valori primitivi, questi metodi verificano se due riferimenti si riferiscono esattamente allo stesso oggetto.
Se si vuole effettivamente esaminare il contenuto di un oggetto, bisogna utilizzare il metodo find()
con la funzione predicato personalizzata.
indexOf()
e lastIndexOf()
accettano un secondo argomento opzionale che specifica l'indice dell'array dal quale iniziare la ricerca. Se questo argomento viene omesso, indexOf()
inizia dall'inizio e lastIndexOf()
inizia dalla fine. I valori negativi sono consentiti per il secondo argomento e vengono trattati come un offset dalla fine dell'array, come accade per il metodo slice()
: un valore di -1, per esempio, specifica l'ultimo elemento dell'array.
La seguente funzione cerca in un array un valore specificato e restituisce un array di tutti gli indici corrispondenti. Questo dimostra come il secondo argomento di indexOf()
può essere utilizzato per trovare corrispondenze oltre la prima.
// Trova tutte le occorrenze di un valore x
// in un array a e restituisce un array
// di indici corrispondenti
function trovatutti(a, x) {
// L'array di indici che restituiremo
let risultati = [];
// La lunghezza dell'array da cercare
let lunghezza = a.length;
// La posizione da cui cercare
let posizione = 0;
// Continua a cercare finché ci sono elementi nell'array
while(posizione < lunghezza) {
// Cerca l'elemento x a partire dalla posizione corrente
posizione = a.indexOf(x, posizione);
// Se non viene trovato, esce dal ciclo
if (posizione === -1) break;
// Altrimenti, memorizza l'indice nell'array dei risultati
risultati.push(posizione);
// Incrementa la posizione per evitare di trovare lo stesso elemento
// nella prossima iterazione
posizione = posizione + 1;
}
return risultati; // Restituisce l'array di indici
}
Si noti che le stringhe hanno metodi indexOf()
e lastIndexOf()
che funzionano come questi metodi di array, tranne che un secondo argomento negativo viene trattato come zero.
includes
Il metodo includes
di ES2016 accetta un singolo argomento e restituisce true
se l'array contiene quel valore o false
altrimenti. Non indica l'indice del valore, ma solo se l'elemento è presente.
Il metodo includes()
è effettivamente un test di appartenenza all'insieme per gli array. Si noti, tuttavia, che gli array non sono una rappresentazione efficiente per gli insiemi, e se si sta lavorando con più di pochi elementi, bisognerebbe utilizzare un vero oggetto Set
per questo scopo (studieremo i Set
nelle prossime lezioni).
Il metodo includes()
è leggermente diverso dal metodo indexOf()
in maniera sostanziale. indexOf()
testa l'uguaglianza utilizzando lo stesso algoritmo che utilizza l'operatore ===
, e quell'algoritmo di uguaglianza considera il valore NaN
diverso da ogni altro valore, incluso se stesso.
includes()
utilizza una versione leggermente diversa di uguaglianza che considera NaN
uguale a se stesso. Questo significa che indexOf()
non rileverà il valore NaN
in un array, ma includes()
lo farà:
let a = [1, true, 3, NaN];
a.includes(true) // => true
a.includes(2) // => false
a.includes(NaN) // => true
a.indexOf(NaN) // => -1; indexOf non può trovare NaN
sort
sort()
ordina gli elementi di un array in place e restituisce l'array ordinato. Quando sort()
viene chiamato senza argomenti, ordina gli elementi dell'array in ordine alfabetico (convertendoli temporaneamente in stringhe per eseguire il confronto, se necessario):
let a = ["banana", "ciliegia", "mela"];
a.sort(); // a == ["banana", "ciliegia", "mela"]
Se un array contiene elementi undefined
, essi vengono ordinati alla fine dell'array.
Per ordinare un array in un ordine diverso da quello alfabetico, bisogna passare una funzione di confronto come argomento a sort()
. Questa funzione decide quale dei suoi due argomenti deve apparire per primo nell'array ordinato. Se il primo argomento deve apparire prima del secondo, la funzione di confronto deve restituire un numero minore di zero. Se il primo argomento deve apparire dopo il secondo nell'array ordinato, la funzione deve restituire un numero maggiore di zero. E se i due valori sono equivalenti (cioè, se il loro ordine è irrilevante), la funzione di confronto deve restituire 0. Quindi, per esempio, per ordinare gli elementi dell'array in ordine numerico anziché alfabetico, si può scrivere una funzione di confronto che sottrae il secondo argomento dal primo:
let a = [33, 4, 1111, 222];
a.sort((a, b) => a - b); // a == [4, 33, 222, 1111]; ordine numerico
Come altro esempio di ordinamento degli elementi dell'array, si potrebbe eseguire un ordinamento alfabetico insensibile alle maiuscole/minuscole su un array di stringhe passando una funzione di confronto che converte entrambi i suoi argomenti in minuscolo (con il metodo toLowerCase()
) prima di confrontarli:
let a = ["formica", "Coleottero", "gatto", "Cane"];
// a == ["Cane","Coleottero","formica","gatto"];
// ordinamento sensibile alle maiuscole/minuscole
a.sort();
// a == ["Cane","Coleottero","formica","gatto"];
// ordinamento insensibile alle maiuscole/minuscole
a.sort(function(s,t) {
let a = s.toLowerCase();
let b = t.toLowerCase();
if (a < b) return -1;
if (a > b) return 1;
return 0;
});
reverse
Il metodo reverse()
inverte l'ordine degli elementi di un array e restituisce l'array invertito. Lo fa sul posto; in altre parole, non crea un nuovo array con gli elementi riorganizzati ma invece li riorganizza nell'array già esistente:
let a = [1,2,3];
a.reverse(); // a == [3,2,1]