Comprovar si un element existeix dins d’un array en Javascript. Sintaxi ES7: includes ()

Introducció

Quan tractem de comprovar si un determinat element existeix dins d’un array en Javascript, tradicionalment hem hagut d’utilitzar mètodes que no estaven inicialment pensats per a això.

Amb la nova proposta ECMAScript 2016 (ES7), tenim a la fi un mètode natiu per a això: includes (). Anem a veure-ho en detall:

Sintaxi

El mètode includes () determina si un arranjament inclou un element determinat, torna true o false segons correspongui.

la seva sintaxi és la següent (l’especificació completa aquí):

a

 Array.prototype.includes (searchElement) 

a

On:

  • searchElement és l’element a cercar.
  • fromIndex és un paràmetre opcional que marca la posició en la matriu a partir de la qual es comença a buscar l’element donat.

exemple bàsic

L’exemple més simple és aquell on busquem un element en un array:

a

 var myArr =; console.info (myArr.includes ( 'donna')); // trueconsole.info (myArr.includes ( 'pensiero')); // false 

a

Cal notar que aquest mètode retorna un Boolean, cosa que el fa diferent a la tradicional indexOf () que hem vingut utilitzant des dels noranta:

a

 console.info (myArr.indexOf ( 'donna')); // 1console.info (myArr.indexOf ( 'pensiero')); // -1 

a

Afortunadament, ara vam guanyar llegibilitat a poder incloure les nostres comprovacions dins d’un flux lògic sense necessitat de convertir el resultat:

a

 // Old / ugly fashion: if (myArr.indexOf ( '')! == -1) {/ * OK, value exists ! * /} // New / nice ES7if (myArr.includes ( '')) {/ * OK, value exists! * /} 

a

Exemples amb índex

Si necessitem fer ús del segon argument, els exemples quedarien així:

a

 console.info (myArr.includes ( 'qual', 5)); // falseconsole.info (myArr.includes ( 'donna', 1)); // trueconsole.info (myArr.includes ( 'vento', -1)); // true 

a

Com a curiositat, podem veure en l’últim exemple que és possible utilitzar un índex negatiu perquè el recompte iniciï des de la dreta.

NOTA : Com és habitual, els resultats durant el treball amb arrays s’ajusten sempre a Índex Zero.

valors especials i expressions

a l’igual que amb valors simples, podem fer comprovacions sobre valors especials i expressions:

a

 // Helper functionvar str = () = > 'donna'; var myArr =; console.info (myArr.includes (NaN)); // trueconsole.info (myArr.includes (Infinity)); // trueconsole.info (myArr.includes (str ())); // trueconsole.info (myArr.includes ( 'senyor')); // false 

a

L’última comprovació exemplifica com includes () requereix d’l’element complet (en aquest cas ‘donna’) per reportar coincidència.

NOTA: la identificació de NaN dins d’un conjunt és una de les novetats d’includes () enfront de indexOf ().

Actuant sobre cadenes

a més de sobre l’objecte Array, includes () també s’ha afegit com un mètode per a l’objecte String, el que ens permet realitzar les comprovacions sobre cadenes de text. En aquest cas, és possible buscar tant paraules i oracions com seqüències de caràcters:

a

 var str = 'en un lloc de la Manxa, del nom del qual no vull recordar, no ha molt de temps que vivia un gentilhome dels de llança en drassana, adarga antiga, rossí flac i llebrer corredor.'; console.info (str.includes ( 'lloc')); // trueconsole.info (str.includes ( 'de l'')); // trueconsole.info (str.includes ( 'ero aco')); // true - > Vull ACOrdarmeconsole.info (str.includes ( 'Manxa', 18)); // trueconsole.info (str.includes ( 'Manxa', 19)); // false 

a

NOTA: El text del Quixot ho he tret d’aquí. Cito la font perquè sembla que hi ha el tema calentet últimament amb aquest text en particular 😉

Un tema important aquí és advertir com el paràmetre fromIndex s’aplica sobre cada lletra, no cada paraula. Per aquest motiu ‘Manxa’ sí estigui entre els 18 + 1 primers caràcters, però no sobre els 19 + 1. El ‘+1’ en cada terme és perquè el recompte comença (com en Array) també en 0.

arrays tipats

El nou mètode també pot aplicar-se sobre arrays tipats:

a

 var typedArr = Uint8Array.of (3, 14, 15); console.info (typedArr.includes (15)); // true 

a

És interessant ressaltar aquí el seu ús amb Uint8ClampedArray, resultat de la feina amb imatges i canvas a través del mètode CanvasRenderingContext2D.getImageData ().

rendiment

És hora de comprovar com rendeix aquest mètode enfront de la tradicional indexOf ().

Per mesurar els temps, utilitzarem la pròpia consola de el navegador i el seu mètode time ().

Com a fonts de dades, utilitzarem 3 arrays de diferent longitud (100, 5000 i 20000), la qual cosa ens permet veure com escalen els temps en funció de l’nombre d’elements sobre el que han de fer la cerca.

el codi preparatori seria el següent:

a

 var prefix = 'item-'; var arr100 = Array.apply (null, {length: 100}) .map ((x, y) = > prefix + i), arr5000 = Array.apply (null, { length: 5000}) .map ((x, y) = > prefix + i), arr20000 = Array.apply (null, {length: 20000}) .map ((x , i) = > prefix + i); var key = (arr) = > prefix + arr.length / 2; // Small sizeconsole.time ( 'searchingItem'); console.info (arr100.length, arr100.includes (key (arr100))); console.timeEnd ( 'searchingItem'); console.time ( 'searchingItem'); console.info (arr100.indexOf (key (arr100))! == -1); console.timeEnd ( 'searchingItem'); // Medium sizeconsole.time ( 'searchingItem'); console.info (arr5000.includes (key (arr5000))); console.timeEnd ( 'searchingItem'); console.time ( 'searchingItem'); console.info (arr5000.indexOf (key (arr5000))! == -1); console.timeEnd ( 'searchingItem'); // Large sizeconsole.time ( 'searchingItem'); console.info (arr20000.includes (key (arr20000))); console.timeEnd ( 'searchingItem'); console.time ( 'searchingItem'); console.info (arr20000.indexOf (key (arr20000))! == -1); console.timeEnd ( 'searchingItem'); 

a

Comprovem cada array amb els dos mètodes que estem comparant (includes i indexOf). El codi resulta una mica repetitiu, però a efectes didàctics resulta molt clar.

Els arrays els creem de forma programàtica, obtenint arranjaments amb aquesta pinta:

a

 

a

La funció ‘key’ compon l’element que anem a buscar al nostre array. Perquè els resultats siguin més precisos, aquesta snippet escull el valor central de cada matriu, el que obliga a l’intèrpret a recórrer un nombre proporcional d’elements en cada test.

Amb tot preparat, vam llançar el nostre script i obtenim els següents resultats:

100 arranjaments 5000 arranjaments 20000 arranjaments
includes () 1.52ms 1.24ms 1.29ms
indexOf () 1.38ms 1.22ms 1.21ms

NOTA: els resultats obtinguts més amunt són els temps mitjans després de 100 execucions.

A la vista de les dades, el nombre d’elements inicial no penalitza, resultant fins i tot més ràpid com més gran és la matriu.

Tampoc s’aprecia una diferència de rendiment entre els mètodes indexOf () i includes () alguna cosa, d’altra banda, habitual en funcionalitats recentment incorporades en els diferents navegadors.

Suport

Com amb totes les funcionalitats emergents de Javascript, cal fer una ullada a el suport d’aquest nou mètode a dia d’avui entre els diferents navegadors:

Chrome Firefox Internet Explorer Edge Opera Safari Android Opera Mobile Safari Mobile Chrome for Android
47 43 No suportat No suportat 34 9 No suportat 34 9 47

Salvant el cas dels navegadors de Microsoft, el suport a dia d’avui (novembre, 2016) és molt complet.

Pollyfill

Per treballar precisam ens amb els navegadors que no suporten de moment aquest mètode (Internet Explorer i Edge), podem implementar aquest ‘pollyfill’. Com és habitual, el recomanable és tirar mà a aquest codi únicament quan no estigui present el mètode de forma nativa.

a

 if (! Array.prototype.includes) {Array.prototype.includes = function (searchElement / *, fromIndex * /) { 'usi strict'; var O = Object (this), len = parseInt (O.length) || 0; // Quick exit if missing data if (len === 0) {return false; } Var n = parseInt (arguments, 10) || 0, k, currentElement; if (n > = 0) {k = n; } Else {k = len + n; if (k < 0) {k = 0; }} While (k < len) {currentElement = O; if (searchElement === currentElement || (searchElement! == searchElement & & currentElement! == currentElement)) {return true; } K ++; } Return false; };} 

a

NOTA: El codi original ha estat extret i re condicionat d’aquí.

Conclusió

Quan programem, resulta trivial determinar si un element donat està present en un array. Fins al moment, requeríem de l’ús de indexOf () i una posterior conversió del seu retorn en un valor booleà.

Amb includes (), el problema es soluciona a l’comptar amb un mètode natiu que funciona correctament i que resulta gramaticalment molt més precís. Si bé la seva pròpia sintaxi pot resultar inapropiada (estem més habituats a instruccions com ‘has ()’ o ‘contains ()’), la seva elecció es deu a salvaguardar la retrocompatibilitat amb aquests mètodes ja definits en altres frameworks d’ús freqüent (MooTools) o en el mateix llenguatge Javascript (Set.prototype.has ()).

Com sempre, tota millora és benvinguda.

Deixa un comentari

L'adreça electrònica no es publicarà. Els camps necessaris estan marcats amb *