Equivalente JavaScript di in_array () di PHP


223

Esiste un modo in JavaScript per confrontare i valori di un array e vedere se si trova in un altro array?

Simile alla in_arrayfunzione di PHP ?

Risposte:


258

No, non ne ha uno. Per questo motivo le librerie più popolari ne hanno una nei loro pacchetti di utilità. Controlla inArray di jQuery e Array.indexOf di Prototype per esempi.

L'implementazione di jQuery è semplice come ci si potrebbe aspettare:

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

Se hai a che fare con una quantità sana di elementi dell'array, il trucco sopra funzionerà bene.

EDIT : Whoops. Non ho nemmeno notato che volevi vedere se un array era dentro un altro. Secondo la documentazione di PHP questo è il comportamento previsto dei PHP in_array:

$a = array(array('p', 'h'), array('p', 'r'), 'o');

if (in_array(array('p', 'h'), $a)) {
    echo "'ph' was found\n";
}

if (in_array(array('f', 'i'), $a)) {
    echo "'fi' was found\n";
}

if (in_array('o', $a)) {
    echo "'o' was found\n";
}

// Output:
//  'ph' was found
//  'o' was found

Il codice pubblicato da Chris e Alex non segue questo comportamento. Alex's è la versione ufficiale dell'indice di PrototypeOf e Chris è più simile a PHP array_intersect. Questo fa quello che vuoi:

function arrayCompare(a1, a2) {
    if (a1.length != a2.length) return false;
    var length = a2.length;
    for (var i = 0; i < length; i++) {
        if (a1[i] !== a2[i]) return false;
    }
    return true;
}

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

E questo il mio test di quanto sopra sopra:

var a = [['p','h'],['p','r'],'o'];
if(inArray(['p','h'], a)) {
    alert('ph was found');
}
if(inArray(['f','i'], a)) {
    alert('fi was found');
}
if(inArray('o', a)) {
    alert('o was found');
}  
// Results:
//   alerts 'ph' was found
//   alerts 'o' was found

Si noti che non ho intenzionalmente esteso il prototipo di array in quanto è generalmente una cattiva idea farlo.


1
jQuery.inArray()non non tornare booleano. Restituisce l'indice dell'elemento trovato o -1 se non trovato
Brad Kent,

A causa dell'elevato punteggio - dovresti contrassegnare la tua risposta come obsoleta
Gerfried

1
questa è la documentazione di indexOf w3schools.com/jsref/jsref_indexof_array.asp
yussan

74

Ora c'è Array.prototype.includes:

Il metodo include () determina se un array include un determinato elemento, restituendo vero o falso come appropriato.

var a = [1, 2, 3];
a.includes(2); // true 
a.includes(4); // false

Sintassi

arr.includes(searchElement)
arr.includes(searchElement, fromIndex)

66

Array.indexOfè stato introdotto in JavaScript 1.6, ma non è supportato nei browser meno recenti. Per fortuna i ragazzi di Mozilla hanno fatto tutto il duro lavoro per te e te lo hanno fornito per la compatibilità:

if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt /*, from*/)
  {
    var len = this.length >>> 0;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}

Ci sono anche alcuni utili frammenti di utilizzo per il tuo piacere di script.


Questa è un'implementazione migliore / più sicura / migliore dei collegamenti / codice pubblicati già qui; le specifiche non richiedono il controllo di array all'interno del pagliaio, ed è quello che vuole l'OP.
Paolo Bergantino,

3
Per inciso, qual è lo scopo di this.length >>> 0? È una conversione in un tipo di numero?
Harto,

3
Array.indexOfè ora standardizzato da ECMAScript Fifth Edition, quindi dovrebbe essere considerato il modo "nativo" di farlo. Tuttavia, dovrai comunque annusare e fornire questo backup per un browser più vecchio per molto tempo. @harto: sì, converte this.lengthin un numero che può essere rappresentato come un intero senza segno a 32 bit. Un nativo Arraypuò avere solo una lunghezza che è già conforme a questo, ma la specifica afferma che è possibile chiamare Array.prototypemetodi su oggetti nativi-JS che non lo sono Array. Questo e l'altro argomento pedante che controlla le cose è garantire l'assoluta conformità alle specifiche.
Bobince,

3
Esiste una diversa versione di polyfill disponibile direttamente da Mozilla - developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
Algy Taylor

@harto rispondo 8 anni dopo il tuo commento, ma forse qualcun altro potrebbe avere la stessa domanda => vedi stackoverflow.com/questions/1822350/…
Frosty Z,

14

Se gli indici non sono in sequenza o se gli indici non sono consecutivi, il codice nelle altre soluzioni elencate qui verrà interrotto. Una soluzione che potrebbe funzionare meglio potrebbe essere:

function in_array(needle, haystack) {
    for(var i in haystack) {
        if(haystack[i] == needle) return true;
    }
    return false;
}

E, come bonus, ecco l'equivalente di array_search di PHP (per trovare la chiave dell'elemento nell'array:

function array_search(needle, haystack) {
    for(var i in haystack) {
        if(haystack[i] == needle) return i;
    }
    return false;
}

Bel calo nella sostituzione. Realizzato il porting da php a node in modo semplice. grazie
Rahim Khoja il

9

Esiste un progetto chiamato Locutus , implementa le funzioni PHP in Javascript e in_array () è incluso, puoi usarlo esattamente come usi in PHP.

Esempi di utilizzo:

in_array('van', myArray);

in_array(1, otherArray, true); // Forcing strict type

4
C'è anche una funzione inArray nelle API di JQuery. Controlla api.jquery.com/jQuery.inArray
ahPo

@ahPo, Nizza! Ma l'implementazione di Locutus ha il vantaggio di essere javascript puro senza dipendenze. Quindi, scegli quello migliore per le tue esigenze
Marcio Mazzucato,

1
oppure puoi semplicemente importare la funzione richiesta da Locutus.
Niket Pathak,


5
var a = [1,2,3,4,5,6,7,8,9];

var isSixInArray = a.filter(function(item){return item==6}).length ? true : false;

var isSixInArray = a.indexOf(6)>=0;

5

La soluzione jQuery è disponibile, controlla la documentazione qui: http://api.jquery.com/jquery.inarray/

$.inArray( 10, [ 8, 9, 10, 11 ] );

3
non dimenticare di controllare in questo modo: if ($. inArray (10, [8, 9, 10, 11])> -1) perché ho fatto così: if ($. inArray (10, [8, 9, 10, 11])) e restituisce sempre true
temirbek

PS: questo è sensibile al tipo, quindi se controlli i numeri assicurati che i tuoi tipi di dati corrispondano! vale a dire: $ .inArray ('10', [8, 9, 10, 11]); restituirebbe -1
Oliver M Grech,


3

Se vuoi solo verificare se un singolo valore è in un array, allora il codice di Paolo farà il lavoro. Se vuoi controllare quali valori sono comuni a entrambi gli array, allora vorrai qualcosa del genere (usando la funzione inArray di Paolo):

function arrayIntersect(a, b) {
    var intersection = [];

    for(var i = 0; i < a.length; i++) {
        if(inArray(b, a[i]))
            intersection.push(a[i]);
    }

    return intersection;
}

Questo restituirà una matrice di valori che si trovano in entrambi ae b. (Matematicamente, questa è un'intersezione dei due array.)

EDIT: vedi il Codice modificato di Paolo per la soluzione al tuo problema. :)


Anche se questo è carino, non è proprio quello che l'OP ha richiesto; non replica la funzionalità di in_array di PHP.
Paolo Bergantino,

3

Se hai bisogno di tutti i parametri PHP disponibili, usa questo:

function in_array(needle, haystack, argStrict) {
    var key = '', strict = !!argStrict;
    if (strict) {
        for (key in haystack) {
            if (haystack[key] === needle) {
                return true;
            }
        }
    }
    else {
        for (key in haystack) {
            if (haystack[key] == needle) {
                return true;
            }
        }
    }
    return false;
}

3

Aggiungi questo codice al tuo progetto e usa i metodi inArray in stile oggetto

if (!Array.prototype.inArray) {
    Array.prototype.inArray = function(element) {
        return this.indexOf(element) > -1;
    };
} 
//How it work
var array = ["one", "two", "three"];
//Return true
array.inArray("one");


2
haystack.find(value => value == needle)

dove il pagliaio è una matrice e l'ago è un elemento nella matrice. Se l'elemento non trovato verrà restituito indefinito altrimenti lo stesso elemento.


1
function in_array(what, where) {
    var a=false;
    for (var i=0; i<where.length; i++) {
        if(what == where[i]) {
            a=true;
            break;
        }
    }
    return a;
}

1

Ho trovato un'ottima soluzione jQuery qui su SO.

var success = $.grep(array_a, function(v,i) {
    return $.inArray(v, array_b) !== -1;
}).length === array_a.length;

Vorrei che qualcuno pubblicasse un esempio di come farlo in caratteri di sottolineatura.


1
function in_array(needle, haystack){

    return haystack.indexOf(needle) !== -1;
}

Ciò restituisce solo se si tratta del primo elemento dell'array; se indexOf(needle) > 0restituirà false
DiMono

0

Un equivalente di in_arraywith underscoreè _.indexOf

Esempi:

_.indexOf([3, 5, 8], 8); // returns 2, the index of 8 _.indexOf([3, 5, 8], 10); // returns -1, not found


0

Se lo utilizzerai in una classe e se preferisci che sia funzionale (e funzioni in tutti i browser):

inArray: function(needle, haystack)
{
    var result = false;

    for (var i in haystack) {
        if (haystack[i] === needle) {
            result = true;
            break;
        }
    }

    return result;
}

Spero che aiuti qualcuno :-)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.