JavaScript equivalente al in_array de PHP ()

223

¿Hay alguna manera en JavaScript de comparar valores de una matriz y ver si está en otra matriz?

¿Similar a la in_arrayfunción de PHP ?

roflwaffle
fuente

Respuestas:

258

No, no tiene uno. Por esta razón, las bibliotecas más populares vienen con una en sus paquetes de utilidad. Consulte jQuery's inArray y Prototype's Array.indexOf para ver ejemplos.

La implementación de jQuery es tan simple como podría esperarse:

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

Si se trata de una cantidad sensata de elementos de matriz, lo anterior funcionará muy bien.

EDITAR : Whoops. Ni siquiera me di cuenta de que querías ver si una matriz estaba dentro de otra. De acuerdo con la documentación de PHP, este es el comportamiento esperado de 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

El código publicado por Chris y Alex no sigue este comportamiento. Alex es la versión oficial del prototipo indexOf, y Chris es más como PHP array_intersect. Esto hace lo que quieres:

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;
}

Y esta es mi prueba de lo anterior:

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

Tenga en cuenta que intencionalmente no extendí el prototipo de matriz, ya que generalmente es una mala idea hacerlo.

Paolo Bergantino
fuente
1
jQuery.inArray()no no volver booleano. Devuelve el índice del elemento encontrado o -1 si no se encuentra
Brad Kent
Debido a la alta calificación, debe marcar su respuesta como obsoleta
Gerfried
1
esta es la documentación de indexOf w3schools.com/jsref/jsref_indexof_array.asp
yussan
74

Ahora hay Array.prototype.includes:

El método incluye () determina si una matriz incluye un determinado elemento, devolviendo verdadero o falso según corresponda.

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

Sintaxis

arr.includes(searchElement)
arr.includes(searchElement, fromIndex)
alemjerus
fuente
66

Array.indexOfse introdujo en JavaScript 1.6, pero no es compatible con navegadores antiguos. Afortunadamente, los muchachos de Mozilla han hecho todo el trabajo duro por ti y te han proporcionado esto por compatibilidad:

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;
  };
}

Incluso hay algunos fragmentos de uso útiles para su placer de secuencias de comandos.

Alex Barrett
fuente
Esta es una implementación mejor / más segura / mejor de los enlaces / código publicados aquí ya; las especificaciones no requieren verificar matrices dentro del pajar, y eso es lo que quiere el OP.
Paolo Bergantino
3
Por cierto, ¿para qué sirve this.length >>> 0? ¿Es eso una conversión a un tipo de número?
harto
3
Array.indexOfahora está estandarizado por la quinta edición de ECMAScript, por lo que debe considerarse la forma "nativa" adecuada de hacerlo. Sin embargo, aún necesitará olfatear y proporcionar esta copia de seguridad para navegadores antiguos durante mucho tiempo. @harto: sí, se convierte this.lengthen un Número que se puede representar como un entero sin signo de 32 bits. Un nativo Arraysolo puede tener una longitud que ya cumpla con esto, pero la especificación establece que puede llamar a Array.prototypemétodos en objetos JS nativos que no lo son Array. Este y el otro argumento pedante de comprobación de cosas es para garantizar el cumplimiento absoluto de las especificaciones.
bobince
3
Hay una versión de polyfill diferente disponible directamente de Mozilla - developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
Algy Taylor
@harto respondo 8 años después de tu comentario, pero tal vez alguien más podría tener la misma pregunta => ver stackoverflow.com/questions/1822350/…
Frosty Z
14

Si los índices no están en secuencia, o si los índices no son consecutivos, el código en las otras soluciones enumeradas aquí se romperá. Una solución que funcionaría algo mejor podría ser:

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

Y, como beneficio adicional, aquí está el equivalente a array_search de PHP (para encontrar la clave del elemento en la matriz:

function array_search(needle, haystack) {
    for(var i in haystack) {
        if(haystack[i] == needle) return i;
    }
    return false;
}
nombre_usuario_aleatorio
fuente
Buena caída en el reemplazo. Realmente es fácil portar desde php a nodo. gracias
Rahim Khoja
9

Hay un proyecto llamado Locutus , implementa funciones PHP en Javascript y se incluye in_array () , puede usarlo exactamente como lo hace en PHP.

Ejemplos de uso:

in_array('van', myArray);

in_array(1, otherArray, true); // Forcing strict type
Marcio Mazzucato
fuente
44
También hay una función inArray en las API de JQuery. Consulte api.jquery.com/jQuery.inArray
ahPo el
@ahPo, bien! Pero la implementación de Locutus tiene la ventaja de ser JavaScript puro sin dependencias. Entonces, elija el mejor para sus necesidades
Marcio Mazzucato
1
o simplemente puede importar la función requerida desde Locutus.
Niket Pathak
7

Simplemente puede usar la función "incluye" como se explica en esta lección en w3schools

parece que

let myArray = ['Kevin', 'Bob', 'Stuart'];
if( myArray.includes('Kevin'))
console.log('Kevin is here');

AbdulRhman Khallil
fuente
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;
Rax Wunter
fuente
5

La solución jQuery está disponible, consulte la documentación aquí: http://api.jquery.com/jquery.inarray/

$.inArray( 10, [ 8, 9, 10, 11 ] );
Webars
fuente
3
no olvide marcar de esta manera: if ($. inArray (10, [8, 9, 10, 11])> -1) porque me gustó esto: if ($. inArray (10, [8, 9, 10, 11])) y siempre vuelve verdadero
temirbek
PD: Esto es sensible al tipo, así que si busca números, ¡asegúrese de que sus tipos de datos coincidan! es decir: $ .inArray ('10', [8, 9, 10, 11]); volvería -1
Oliver M Grech
3

Si solo desea verificar si un solo valor está en una matriz, entonces el código de Paolo hará el trabajo. Si desea verificar qué valores son comunes a ambas matrices, entonces querrá algo como esto (usando la función inArray de 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;
}

Esto devolverá una matriz de valores que están en ambos ay b. (Matemáticamente, esta es una intersección de las dos matrices).

EDITAR: Vea el Código Editado de Paolo para la solución a su problema. :)

Chris Doble
fuente
Aunque esto es bueno, no es realmente lo que solicitó el OP; no replica la funcionalidad de in_array de PHP.
Paolo Bergantino
3

Si necesita todos los parámetros PHP disponibles, use esto:

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;
}
Andres SK
fuente
3

Agregue este código a su proyecto y use el estilo de objeto en los métodos de matriz

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");
Никита Овчинников
fuente
2
haystack.find(value => value == needle)

donde haystack es una matriz y aguja es un elemento en la matriz. Si el elemento no encontrado se devolverá indefinido, de lo contrario, el mismo elemento.

Emmanuel de Carvalho Garcia
fuente
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;
}
Priya
fuente
1

Encontré una gran solución jQuery aquí en SO.

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

Desearía que alguien publicara un ejemplo de cómo hacer esto en subrayado.

pymarco
fuente
1
function in_array(needle, haystack){

    return haystack.indexOf(needle) !== -1;
}
Crisswalt
fuente
Esto solo devuelve si es el primer elemento de la matriz; si indexOf(needle) > 0volverá falso
DiMono
0

Un equivalente de in_arraywith underscorees _.indexOf

Ejemplos:

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

Bogdan D
fuente
0

Si lo va a usar en una clase, y si prefiere que sea funcional (y que funcione en todos los navegadores):

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

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

    return result;
}

Espero que ayude a alguien :-)

MageParts
fuente