it-swarm.it

Controlla se un elemento è presente in un array

La funzione che sto usando ora per verificare questo è la seguente:

function inArray(needle,haystack)
{
    var count=haystack.length;
    for(var i=0;i<count;i++)
    {
        if(haystack[i]===needle){return true;}
    }
    return false;
}

Funziona. Quello che sto cercando è se c'è un modo migliore per farlo.

432
Francisc

ECMAScript 2016 incorpora un metodo includes() per gli array che risolve in modo specifico il problema, e ora è il metodo preferito.

[1, 2, 3].includes(2);     // true
[1, 2, 3].includes(4);     // false
[1, 2, 3].includes(1, 2);  // false (second parameter is the index position in this array at which to begin searching)

A partire da LUGLIO 2018, questo è stato implementato in quasi tutti i browser major, se è necessario supportare IE a polyfill è disponibile.

758
Alister

Codice:

function isInArray(value, array) {
  return array.indexOf(value) > -1;
}

Esecuzione:

isInArray(1, [1,2,3]); // true

Aggiornamento (2017):

Nei browser moderni che seguono lo standard ECMAScript 2016 (ES7), è possibile utilizzare la funzione Array.prototype.includes , che rende molto più semplice controllare se un elemento è presente in un array:

const array = [1, 2, 3];
const value = 1;
const isInArray = array.includes(value);
console.log(isInArray); // true
389

Basta usare indexOf :

haystack.indexOf(needle) >= 0

Se vuoi supportare i vecchi Internet Explorer (<IE9), dovrai includere il tuo codice corrente come soluzione alternativa .

A meno che la lista non sia ordinata, è necessario confrontare ogni valore con l'ago. Pertanto, sia la soluzione che indexOf dovranno eseguire il confronto n/2 in media. Tuttavia, poiché indexOf è un metodo integrato, potrebbe utilizzare ulteriori ottimizzazioni e sarà leggermente più veloce nella pratica. Si noti che, a meno che l'applicazione non effettui ricerche negli elenchi molto spesso (diciamo 1000 volte al secondo) o le liste siano enormi (ad esempio voci da 100k), la differenza di velocità non avrà importanza.

71
phihag

L'ho confrontato più volte su Google Chrome 52, ma sentiti libero di copypaste in qualsiasi altra console del browser.


~ 1500 ms, include (~ 2700 ms quando ho usato il polyfill )

var array = [0,1,2,3,4,5,6,7,8,9]; 
var result = 0;

var start = new Date().getTime();
for(var i = 0; i < 10000000; i++)
{
  if(array.includes("test") === true){ result++; }
}
console.log(new Date().getTime() - start);

~ 1050 ms, indexOf

var array = [0,1,2,3,4,5,6,7,8,9]; 
var result = 0;

var start = new Date().getTime();
for(var i = 0; i < 10000000; i++)
{
  if(array.indexOf("test") > -1){ result++; }
}
console.log(new Date().getTime() - start);

~ 650 ms, funzione personalizzata

function inArray(target, array)
{

/* Caching array.length doesn't increase the performance of the for loop on V8 (and probably on most of other major engines) */

  for(var i = 0; i < array.length; i++) 
  {
    if(array[i] === target)
    {
      return true;
    }
  }

  return false; 
}

var array = [0,1,2,3,4,5,6,7,8,9]; 
var result = 0;

var start = new Date().getTime();
for(var i = 0; i < 10000000; i++)
{
  if(inArray("test", array) === true){ result++; }
}
console.log(new Date().getTime() - start);

Codice riga singola .. restituirà vero o falso

!!(arr.indexOf("val")+1)
20
Akarsh Satija

Puoi usare indexOf ma non funziona bene nell'ultima versione di Internet Explorer. Codice:

function isInArray(value, array) {
  return array.indexOf(value) > -1;
}

Esecuzione:

isInArray(1, [1,2,3]); // true

Ti suggerisco di usare il seguente codice:

function inArray(needle, haystack) {
 var length = haystack.length;
 for (var i = 0; i < length; i++) {
 if (haystack[i] == needle)
  return true;
 }
 return false;
}
14
user2598812

Puoi utilizzare la funzione _contains dalla libreria underscore.js per ottenere ciò:

if (_.contains(haystack, needle)) {
  console.log("Needle found.");
};
8
Chris Alley

Dal momento che ECMAScript6, si può usare Set:

var myArray = ['A', 'B', 'C'];
var mySet = new Set(myArray);
var hasB = mySet.has('B'); // true
var hasZ = mySet.has('Z'); // false
4
Nicolas

A seconda delle dimensioni dell'ago che stai cercando Array.filter potrebbe essere utile. Ecco un esempio:

let filtered, arr = ['Haystack', 'Needle'];
filtered = arr.filter((elem) => {
  return elem.toLowerCase() === 'needle';
});
// filtered => ['needle']
2
Josh Habdas

In lodash puoi usare _.includes (che alias anche per _.contains)

Puoi cercare l'intero array:

_.includes([1, 2, 3], 1); // true

Puoi cercare l'array da un indice iniziale:

_.includes([1, 2, 3], 1, 1);  // false (begins search at index 1)

Cerca una stringa:

_.includes('pebbles', 'eb');  // true (string contains eb)

Funziona anche per il controllo di matrici semplici di oggetti:

_.includes({ 'user': 'fred', 'age': 40 }, 'fred');    // true
_.includes({ 'user': 'fred', 'age': false }, false);  // true

Una cosa da notare sull'ultimo caso è che funziona per le primitive come stringhe, numeri e booleani ma non può cercare attraverso matrici o oggetti

_.includes({ 'user': 'fred', 'age': {} }, {});   // false
_.includes({ 'user': [1,2,3], 'age': {} }, 3);   // false
0
Connor Leech