Pregunta ¿La mejor forma de encontrar si un artículo está en una matriz de JavaScript? [duplicar]


Esta pregunta ya tiene una respuesta aquí:

¿Cuál es la mejor manera de encontrar si un objeto está en una matriz?

Esta es la mejor forma 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

687
2017-09-27 15:41


origen


Respuestas:


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

EDITAR: Sin embargo, esto no funcionará en IE6, 7 u 8. La mejor solución es definirla usted 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 Jamesversión de s:

    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. roosteronacidversión de s:

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

646
2017-09-27 15:45



Si está usando jQuery:

$.inArray(5 + 5, [ "8", "9", "10", 10 + "" ]);

Para más información: http://api.jquery.com/jQuery.inArray/


203
2018-03-27 00:37



Primero, implementar indexOf en JavaScript para navegadores que aún no lo tienen. Por ejemplo, ver Extras de la matriz de Erik Arvidsson (también el publicación de blog asociada) Y luego puedes usar indexOf sin preocuparse por el soporte del navegador. Aquí hay una versión ligeramente optimizada de su indexOf implementació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;
    };
}

Ha cambiado para almacenar la longitud para que no tenga que buscarla en cada iteración. Pero la diferencia no es enorme. Una función de propósito menos general podría ser más rápida:

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

Prefiero usar la función estándar y dejar este tipo de micro-optimización para cuando realmente se necesite. Pero si está interesado en la micro-optimización, adapté el puntos de referencia ese galonononato unido a los comentarios, a benchmark buscando en matrices. Sin embargo, son bastante crudos, una investigación completa probaría arreglos con diferentes tipos, diferentes longitudes y encontrar objetos que ocurren en diferentes lugares.


32
2017-09-27 18:10



Si la matriz no está ordenada, en realidad no hay una mejor manera (aparte de usar el indexOf mencionado anteriormente, que creo que equivale a lo mismo). Si la matriz está ordenada, puede hacer una búsqueda binaria, que funciona así:

  1. Elige el elemento medio de la matriz.
  2. ¿El elemento que estás buscando es más grande que el elemento que elegiste? Si es así, eliminaste la mitad inferior de la matriz. Si no es así, eliminaste la mitad superior.
  3. Elija el elemento medio de la mitad restante de la matriz y continúe como en el paso 2, eliminando las mitades de la matriz restante. Finalmente, encontrará su elemento o no tendrá ninguna matriz para ver.

La búsqueda binaria se ejecuta en el tiempo proporcional al logaritmo de la longitud de la matriz, por lo que puede ser mucho más rápido que mirar cada elemento individual.


10
2017-09-27 15:50



asumiendo .indexOf() está implementado

Object.defineProperty( Array.prototype,'has',
{
    value:function(o, flag){
    if (flag === undefined) {
        return this.indexOf(o) !== -1;
    } else {   // only for raw js object
        for(var v in this) {
            if( JSON.stringify(this[v]) === JSON.stringify(o)) return true;
        }
        return false;                       
    },
    // writable:false,
    // enumerable:false
})

!!! No hagas Array.prototype.has=function(){... porque agregará un elemento enumerable en cada matriz y js está roto.

//use like          
[22 ,'a', {prop:'x'}].has(12) // false
["a","b"].has("a") //  true

[1,{a:1}].has({a:1},1) // true
[1,{a:1}].has({a:1}) // false

el uso de la segunda arg (bandera) fuerza la comparación por valor en lugar de referencia


9
2018-02-24 18:11



Depende de tu propósito. Si programa para la Web, evite indexOf, no es compatible con Internet Explorer 6 (¡muchos de ellos aún se usan!), o hace uso condicional:

if (yourArray.indexOf !== undefined) result = yourArray.indexOf(target);
else result = customSlowerSearch(yourArray, target);

indexOf probablemente esté codificado en código nativo, por lo que es más rápido que cualquier cosa que pueda hacer en JavaScript (excepto la búsqueda binaria / dicotomía si la matriz es apropiada). Nota: es una cuestión de gusto, pero haría una return false;al final de tu rutina, para devolver un verdadero booleano ...


5
2017-09-27 16:28



Aquí hay algunos metaconocimientos para usted: si desea saber qué puede hacer con una matriz, consulte la documentación. Aquí tiene la página Array para Mozilla.

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array

Allí verás una referencia a indexOf, agregado en Javascript 1.6


4
2017-09-27 15:51



Aquí se detalla una forma robusta de verificar si un objeto es una matriz en javascript:

Aquí hay dos funciones de xa.js marco que adjunto a una utils = {} 'envase'. Esto debería ayudarlo a detectar matrices correctamente.

var utils = {};

/**
 * utils.isArray
 *
 * Best guess if object is an array.
 */
utils.isArray = function(obj) {
     // do an instanceof check first
     if (obj instanceof Array) {
         return true;
     }
     // then check for obvious falses
     if (typeof obj !== 'object') {
         return false;
     }
     if (utils.type(obj) === 'array') {
         return true;
     }
     return false;
 };

/**
 * utils.type
 *
 * Attempt to ascertain actual object type.
 */
utils.type = function(obj) {
    if (obj === null || typeof obj === 'undefined') {
        return String (obj);
    }
    return Object.prototype.toString.call(obj)
        .replace(/\[object ([a-zA-Z]+)\]/, '$1').toLowerCase();
};

Si luego quieres verificar si un objeto está en una matriz, también incluiría este código:

/**
 * Adding hasOwnProperty method if needed.
 */
if (typeof Object.prototype.hasOwnProperty !== 'function') {
    Object.prototype.hasOwnProperty = function (prop) {
        var type = utils.type(this);
        type = type.charAt(0).toUpperCase() + type.substr(1);
        return this[prop] !== undefined
            && this[prop] !== window[type].prototype[prop];
    };
}

Y finalmente esta función in_array:

function in_array (needle, haystack, strict) {
    var key;

    if (strict) {
        for (key in haystack) {
            if (!haystack.hasOwnProperty[key]) continue;

            if (haystack[key] === needle) {
                return true;
            }
        }
    } else {
        for (key in haystack) {
            if (!haystack.hasOwnProperty[key]) continue;

            if (haystack[key] == needle) {
                return true;
            }
        }
    }

    return false;
}

3
2017-08-17 12:57