In ambito frontend, in particolar modo lavorando a stretto contatto con JS, capita il più delle volte di utilizzare Array per immagazzinare dati.
const _var = ['🤖','👽','☠️','🎅','🐨','🐧','💀'];E molto spesso è necessario cercare elementi all’interno di questo set di dati: potrebbe servire trovare l’indice dell’elemento, o semplicemente sapere se l’elemento è presente… oppure ottenere un subset di elementi che rispettano un certo criterio.
Con l’avvento di ES6, sono stati introdotti molti metodi per le ricerche sugli Array.
Metodi utili ricerca su array
| Metodo | Utilità | Ritorno |
|---|---|---|
| .includes | Ritorna true/false se il valore cercato esiste nell’array | bool |
| .find | Ritorna il primo elemento dell’array che soddisfa il criterio di ricerca oppure undefined se non trovato | object | undefined |
| .filter | Ritorna un nuovo array contenente gli elementi dal set originario che soddisfano il criterio di ricerca | Array |
| .indexOf | Ritorna il primo indice dell’elemento nel set se esiste, altrimenti ritorna -1 | Number |
Quindi
- Devo trovare se un elemento è presente in un array: posso usare .includes() direttamente, oppure verificare che .find() sia diverso da
undefined, oppure verificare che .indexOf() sia diverso da -1 - Devo trovare l’indice preciso di dove è presente l’elemento: indubbiamente la .indexOf() è il miglior metodo
- Mi serve esattamente l’elemento che rispetta dei criteri all’interno dell’array: .find() o .filter() in caso di più valori (subset)
L’elemento è presente nell’array?
const people = ['🤖','👽','☠️','🎅','🐨','🐧','💀'];
//using includes
let isKoalaPresent = people.includes('🐨');
//using find
let isAlienPresent = typeof (people.find((el) => el === '👽')) !== 'undefined';
//using indexOf
let isRobotPresent = people.indexOf('🤖') !== -1;Una necessità ad esempio potrebbe essere l’aggiungere, nel nostro set di dati, un Clown dopo Babbo Natale. Banalmente dovremmo trovare la posizione di Babbo Natale e posizionare successivamente il Clown.
Indice di un elemento nel set di dati
let people = ['🤖','👽','☠️','🎅','🐨','🐧','💀'];
let santaClausPosition = people.indexOf('🎅'); //3
// splice: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice?retiredLocale=it
// position of 🤡 is after 🎅, so ++santaClausPosition
people.splice(++santaClausPosition, 0, '🤡');
console.log(people);
//['🤖','👽','☠️','🎅','🤡','🐨','🐧','💀']tldr
Anche se sia santaClausPosition++ che ++santaClausPosition incrementano la variabile a cui sono applicati, il risultato restituito da santaClausPosition++ è il valore della variabile prima dell’incremento, mentre il risultato restituito da ++santaClausPosition è il valore della variabile dopo che l’incremento è stato applicato.
tips
.indexOf può restituire l’indice dell’elemento in un array anche a partire da una certa posizione: in questo caso basta passare un intero come secondo parametro del metodo.
Inoltre, se si vuole iniziare la ricerca non dall’inizio ma dalla fine, esiste il metodo .lastIndexOf
let people = ['🤖','👽','☠️','🎅','🐨','🐧','🎅','💀'];
let santaClausPosition = people.indexOf('🎅', 4); //6Elementi da array
Supponiamo di avere un set di dati che rappresenta delle stanze con degli individui all’interno.
let environment = [
{
name: 'Space Room',
people: ['👽','🤖','👾'],
type: 'ROBOT_ALIEN',
},
{
name: 'Animal Court',
people: ['🐨','🐧'],
type: 'ANIMAL',
},
{
name: 'Attention Field',
people: ['💀','☠️','👾'],
type: 'SKULL',
},
{
name: 'Magic Room',
people: ['🎅','🤡'],
type: 'MAGIC',
}
];Vorrei trovare la stanza relativa agli animali.
let animalsRoom = environment.find((room) => room.type === 'ANIMAL');
console.log(animalsRoom);
/*
{
name: 'Animal Court',
people: ['🐨','🐧'],
type: 'ANIMAL'
}
*/
// NB: `(room) => room.type === 'ANIMAL'` è il criterio di ricerca.
// Qualora il criterio relativo a room, torni true allora room
// è un elemento accettato dal find.Magari invece vorrei proprio la stanza dove è presente l’Alieno…
let alienRoom = environment.find((room) => room.people.includes('👽'));
console.log(alienRoom);
/*
{
name: 'Space Room',
people: ['👽','🤖','👾'],
type: 'ROBOT_ALIEN'
}
*/Nel caso invece di voler ottenere un sottoinsieme di dati potremmo usare .filter(). Per approfondire puoi anche vederlo in azione qui.
In realtà anche se è stato sviscerato in un precedente articolo, vorrei farvelo vedere in azione combinandolo con il concat(), per ottenere un array flatten da più sorgenti di dati. Ad esempio vorrei ottenere tutti i robot eventualmente presenti nelle varie stanze.
let filterRobot = (el) => el.includes('🤖') || el.includes('👾');
let robotPeoples = environment.filter((room) => filterRobot(room.people))
.map((el) => el.people.filter((entity) => filterRobot(entity)));
let robots = [].concat.apply([], robotPeoples);
console.log(robots);
//['🤖', '👾', '👾']In questo articolo abbiamo visto, anche tramite qualche esempio pratico, un basilare approccio alla ricerca di elementi negli array in Javascript ES6+.
Combinando Array.filter(), Array.find(), Array.includes(), Array.indexOf() con .map() e .reduce() abbiamo un set di strumenti potentissimo per la manipolazione dei dati su Array.