¿Cómo verifico si una matriz incluye un valor en JavaScript?

Resuelto brad asked hace 15 años • 62 respuestas

¿Cuál es la forma más concisa y eficaz de saber si una matriz de JavaScript contiene un valor?

Esta es la única manera que conozco de hacerlo:

function contains(a, obj) {
    for (var i = 0; i < a.length; i++) {
        if (a[i] === obj) {
            return true;
        }
    }
    return false;
}

¿Existe una forma mejor y más concisa de lograr esto?

Esto está muy relacionado con la pregunta de Stack Overflow. ¿La mejor manera de encontrar un elemento en una matriz de JavaScript? que aborda la búsqueda de objetos en una matriz usando indexOf.

brad avatar Oct 26 '08 05:10 brad
Aceptado

Los navegadores modernos tienen Array#includes, que hace exactamente eso y es ampliamente compatible con todos excepto IE:

console.log(['joe', 'jane', 'mary'].includes('jane')); // true
Expandir fragmento

También puedes usar Array#indexOf, que es menos directo, pero no requiere polyfills para navegadores obsoletos.

console.log(['joe', 'jane', 'mary'].indexOf('jane') >= 0); // true
Expandir fragmento


Muchos marcos también ofrecen métodos similares:

  • jQuery:$.inArray(value, array, [fromIndex])
  • Underscore.js: _.contains(array, value)(también conocido como _.includey _.includes)
  • Kit de herramientas de Dojo:dojo.indexOf(array, value, [fromIndex, findLast])
  • Prototipo:array.indexOf(value)
  • MooHerramientas:array.indexOf(value)
  • MochiKit:findValue(array, value)
  • MS Ajax:array.indexOf(value)
  • Extensión:Ext.Array.contains(array, value)
  • Lodash: _.includes(array, value, [from])(es _.containsanterior a 4.0.0)
  • Ramda:R.includes(value, array)

Observe que algunos marcos implementan esto como una función, mientras que otros agregan la función al prototipo de matriz.

codeape avatar Sep 24 '2009 19:09 codeape

Actualización de 2019: esta respuesta es de 2008 (¡11 años!) y no es relevante para el uso moderno de JS. La mejora de rendimiento prometida se basó en una prueba comparativa realizada en navegadores de esa época. Puede que no sea relevante para los contextos de ejecución JS modernos. Si necesita una solución fácil, busque otras respuestas. Si necesita el mejor rendimiento, compare usted mismo en los entornos de ejecución relevantes.

Como han dicho otros, la iteración a través de la matriz es probablemente la mejor manera, pero se ha demostrado que un whilebucle decreciente es la forma más rápida de iterar en JavaScript. Por lo tanto, es posible que desee reescribir su código de la siguiente manera:

function contains(a, obj) {
    var i = a.length;
    while (i--) {
       if (a[i] === obj) {
           return true;
       }
    }
    return false;
}

Por supuesto, también puedes ampliar el prototipo de Array:

Array.prototype.contains = function(obj) {
    var i = this.length;
    while (i--) {
        if (this[i] === obj) {
            return true;
        }
    }
    return false;
}

Y ahora puedes simplemente usar lo siguiente:

alert([1, 2, 3].contains(2)); // => true
alert([1, 2, 3].contains('2')); // => false
Damir Zekić avatar Oct 25 '2008 23:10 Damir Zekić

Las respuestas principales asumen tipos primitivos, pero si desea saber si una matriz contiene un objeto con algún rasgo, Array.prototype.some() es una solución elegante:

const items = [ {a: '1'}, {a: '2'}, {a: '3'} ]

items.some(item => item.a === '3')  // returns true
items.some(item => item.a === '4')  // returns false

Lo bueno de esto es que la iteración se cancela una vez que se encuentra el elemento, por lo que se ahorran ciclos de iteración innecesarios.

Además, encaja muy bien en una ifdeclaración ya que devuelve un valor booleano:

if (items.some(item => item.a === '3')) {
  // do something
}

* Como Jamess señaló en el comentario, en el momento de esta respuesta, septiembre de 2018, Array.prototype.some()es totalmente compatible: tabla de soporte de caniuse.com

Michael avatar Jul 18 '2014 14:07 Michael

indexOftal vez, pero es una "extensión de JavaScript del estándar ECMA-262; como tal, puede que no esté presente en otras implementaciones del estándar".

Ejemplo:

[1, 2, 3].indexOf(1) => 0
["foo", "bar", "baz"].indexOf("bar") => 1
[1, 2, 3].indexOf(4) => -1

AFAICS Microsoft no ofrece ningún tipo de alternativa a esto, pero puede agregar una funcionalidad similar a las matrices en Internet Explorer (y otros navegadores que no son compatibles indexOf) si lo desea, como lo revela una búsqueda rápida en Google (por ejemplo, este ).

andreas avatar Oct 25 '2008 22:10 andreas

ECMAScript 7 presenta Array.prototype.includes.

Se puede utilizar así:

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

También acepta un segundo argumento opcional fromIndex:

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

A diferencia de indexOf, que utiliza Strict Equality Comparison , includescompara utilizando el algoritmo de igualdad SameValueZero . Eso significa que puedes detectar si una matriz incluye NaN:

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

Además, a diferencia de indexOf, includesno omite los índices faltantes:

new Array(5).includes(undefined); // true

Se puede rellenar para que funcione en todos los navegadores.

Oriol avatar Jan 01 '2015 01:01 Oriol

Digamos que has definido una matriz como esta:

const array = [1, 2, 3, 4]

A continuación se muestran tres formas de comprobar si hay un 3allí. Todos regresan o trueo false.

Método Native Array (desde ES2016) ( tabla de compatibilidad )

array.includes(3) // true

Como método de matriz personalizado (anterior a ES2016)

// Prefixing the method with '_' to avoid name clashes
Object.defineProperty(Array.prototype, '_includes', { value: function (v) { return this.indexOf(v) !== -1 }})
array._includes(3) // true

Función sencilla

const includes = (a, v) => a.indexOf(v) !== -1
includes(array, 3) // true
william malo avatar Mar 24 '2012 04:03 william malo