741 votos

La mejor manera de encontrar un elemento en un array de JavaScript?

Posibles Duplicados:
array.contains(obj) en JavaScript

¿Cuál es la mejor manera de saber si un objeto está en un array?

Esta es la mejor manera que conozco:

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

include([1,2,3,4], 3); // true
include([1,2,3,4], 6); // undefined

687voto

Vinko Vrsalovic Puntos 116138
function include(arr,obj) {
    return (arr.indexOf(obj) != -1);
}

EDICIÓN: Esto no funciona en IE6, 7 y 8, aunque. La mejor solución es definir a ti mismo si no está presente:

  1. Mozilla (ECMA-262) versión:

      if (!Array.prototype.indexOf)
      {
    
           Array.prototype.indexOf = function(searchElement /*, fromIndex */)
    
        {
    
    
        "use strict";
    
        if (this === void 0 || this === null)
          throw new TypeError();
    
        var t = Object(this);
        var len = t.length >>> 0;
        if (len === 0)
          return -1;
    
        var n = 0;
        if (arguments.length > 0)
        {
          n = Number(arguments[1]);
          if (n !== n)
            n = 0;
          else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0))
            n = (n > 0 || -1) * Math.floor(Math.abs(n));
        }
    
        if (n >= len)
          return -1;
    
        var k = n >= 0
              ? n
              : Math.max(len - Math.abs(n), 0);
    
        for (; k < len; k++)
        {
          if (k in t && t[k] === searchElement)
            return k;
        }
        return -1;
      };
    
    }
    
  2. Daniel James's versión:

    if (!Array.prototype.indexOf) {
      Array.prototype.indexOf = function (obj, fromIndex) {
        if (fromIndex == null) {
            fromIndex = 0;
        } else if (fromIndex < 0) {
            fromIndex = Math.max(0, this.length + fromIndex);
        }
        for (var i = fromIndex, j = this.length; i < j; i++) {
            if (this[i] === obj)
                return i;
        }
        return -1;
      };
    }
    
  3. roosteronacid's versión:

    Array.prototype.hasObject = (
      !Array.indexOf ? function (o)
      {
        var l = this.length + 1;
        while (l -= 1)
        {
            if (this[l - 1] === o)
            {
                return true;
            }
        }
        return false;
      } : function (o)
      {
        return (this.indexOf(o) !== -1);
      }
    );
    

207voto

GerManson Puntos 3238

Si usted está usando jQuery:

http://api.jquery.com/jQuery.inArray/

33voto

Daniel James Puntos 2889

En primer lugar, implementar indexOf en JavaScript para navegadores que no lo tienes ya. Ver, por ejemplo, Erik Arvidsson de la matriz de extras (además, el asociado blog). Y, a continuación, puede utilizar indexOf sin tener que preocuparse acerca de la compatibilidad del navegador. Aquí un poco optimizada versión de su indexOf aplicación:

if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function (obj, fromIndex) {
        if (fromIndex == null) {
            fromIndex = 0;
        } else if (fromIndex < 0) {
            fromIndex = Math.max(0, this.length + fromIndex);
        }
        for (var i = fromIndex, j = this.length; i < j; i++) {
            if (this[i] === obj)
                return i;
        }
        return -1;
    };
}

Lo que ha cambiado para almacenar la longitud de forma que no es necesario buscarla en cada iteración. Pero la diferencia no es enorme. Una menor función de propósito general puede ser más rápido:

var include = Array.prototype.indexOf ?
    function(arr, obj) { return arr.indexOf(obj) !== -1; } :
    function(arr, obj) {
        for(var i = -1, j = arr.length; ++i < j;)
            if(arr[i] === obj) return true;
        return false;
    };

Yo prefiero usar la función estándar y salir de esta suerte de micro-optimización para cuando es realmente necesaria. Pero si usted está interesado en micro-optimización he adaptado los parámetros que roosterononacid vinculados a los comentarios, a la búsqueda de referencia en matrices. Son bastante crudo sin embargo, una investigación completa sería la prueba de matrices con diferentes tipos, de diferente longitud y la búsqueda de objetos que se producen en distintos lugares.

11voto

assortedslog Puntos 81

Si la matriz no está ordenado, no hay realmente una manera mejor (aparte de usar el mencionado porcentaje, que creo que viene a ser lo mismo). Si el array está ordenado, usted puede hacer una búsqueda binaria, la cual funciona como esto:

  1. Elegir el medio de los elementos de la matriz.
  2. Es el elemento que está buscando más grande que el elemento elegido? Si es así, usted ha eliminado la mitad inferior de la matriz. Si no lo está, se ha eliminado la mitad superior.
  3. Elegir el medio de los elementos de la restante mitad de la matriz, y continuar en el paso 2, la eliminación de las mitades de la matriz restantes. Eventualmente vas a encontrar su elemento, o no tienen la matriz de la izquierda para mirar a través.

Búsqueda binaria ejecuta en un tiempo proporcional al logaritmo de la longitud de la matriz, por lo que puede ser mucho más rápido que buscar en cada elemento individual.

10voto

adrian Puntos 339

suponiendo .indexOf() se implementa puede implementar algo similar a obj.hasOwnProperty(prop)

Object.defineProperty( Array.prototype,'has',
         {
            value:function(o){return this.indexOf(o)!=-1},
            // writable:false,
            // enumerable:false
         }
   )

ahora el nuevo método que puede ser utilizado como

[22 ,'a', {prop:'x'}].has(12) 

devolviendo false

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by: