Meilleure façon de savoir si un élément est dans un tableau JavaScript? [dupliquer]

cette question a déjà une réponse ici:

Quelle est la meilleure façon de savoir si un objet est dans un tableau?

C'est le meilleur moyen que je connaisse:

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
698
demandé sur Michał Perłakowski 2008-09-27 19:41:12

8 réponses

à partir de ECMAScript 2016, vous pouvez utiliser includes()

arr.includes(obj);

si vous voulez prendre en charge IE ou d'autres navigateurs plus anciens:

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

EDIT: Cela ne fonctionnera pas sur IE6, 7 ou 8 cependant. La meilleure solution est de la définir vous-même si elle n'est pas présente:

  1. Mozilla's (ECMA-262) version:

      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 version:

    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 version:

    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);
      }
    );
    
655
répondu Vinko Vrsalovic 2018-08-16 09:37:57

si vous utilisez jQuery:

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

pour plus d'informations: http://api.jquery.com/jQuery.inArray /

202
répondu GerManson 2016-04-23 04:28:24

tout d'abord, implémenter indexOf en JavaScript pour les navigateurs qui ne l'ont pas déjà. Par exemple, voir les extras de tableau D'Erik Arvidsson (aussi, le post de blog associé ). Et puis vous pouvez utiliser indexOf sans vous soucier du support du navigateur. Voici une version légèrement optimisée de son implémentation indexOf :"

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

Il a changé pour stocker la longueur de sorte qu'il n'a pas besoin de le chercher chaque itération. Mais la différence n'est pas énorme. Une fonction moins générale pourrait être plus rapide:

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

je préfère utiliser la fonction standard et laisser cette sorte de micro-optimisation pour quand il est vraiment nécessaire. Mais si vous êtes passionné par la micro-optimisation, j'ai adapté le benchmarks que roosterononacid lié dans les commentaires, à recherche de benchmark dans les tableaux . Ils sont assez brut, un plein la recherche permettrait de tester des tableaux de différents types, de différentes longueurs et de trouver des objets qui se produisent à différents endroits.

32
répondu Daniel James 2012-07-26 15:21:04

si le tableau n'est pas trié, il n'y a pas vraiment de meilleur moyen (à part l'utilisation de l'indexOf mentionné ci-dessus, qui je pense revient à la même chose). Si le tableau est trié, vous pouvez faire une recherche binaire, qui fonctionne comme ceci:

  1. choisissez l'élément central du tableau.
  2. est-ce que l'élément que vous recherchez est plus grand que l'élément que vous avez choisi? Si oui, vous avez éliminé la moitié inférieure du tableau. Si ce n'est pas le cas, vous avez éliminé la moitié supérieure.
  3. choisir l'élément central de la moitié restante du tableau, et continuer comme dans l'étape 2, éliminant les moitiés du tableau restant. Vous finirez soit par trouver votre élément, soit par ne plus avoir de tableau à regarder.

la recherche binaire s'exécute dans un temps proportionnel au logarithme de la longueur du tableau, de sorte qu'elle peut être beaucoup plus rapide que la recherche de chaque élément individuel.

10
répondu assortedslog 2008-09-27 16:00:52

en supposant que .indexOf() est mis en œuvre

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

!!! ne faites pas Array.prototype.has=function(){... parce que vous allez ajouter un élément énumérable dans chaque tableau et js est cassé.

//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

l'utilisation de 2nd arg (drapeau) forces comparation by value instead of reference

9
répondu bortunac 2017-11-20 02:29:11

Cela dépend de votre but. Si vous programmez pour le Web, évitez indexOf , il n'est pas pris en charge par Internet Explorer 6 (beaucoup d'entre eux encore utilisés!), ou à usage conditionnel:

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

indexOf est probablement codé en code natif, il est donc plus rapide que tout ce que vous pouvez faire en JavaScript (sauf recherche binaire/dichotomie si le tableau est approprié). Remarque: c'est une question de goût, mais je voudrais faire une return false; à la fin de votre routine, de retour d'un vrai Booléen...

5
répondu PhiLho 2011-08-11 23:55:56

voici quelques méta-connaissances pour vous - si vous voulez savoir ce que vous pouvez faire avec un tableau, consultez la documentation-voici la page du tableau pour Mozilla

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

là, vous verrez référence à indexOf, ajouté en Javascript 1.6

4
répondu Paul Dixon 2012-11-02 02:16:48

une manière robuste de vérifier si un objet est un tableau en javascript est détaillé ici:

voici deux fonctions du xa.js cadre que j'attache à un utils = {} "conteneur". Ceux-ci devraient vous aider à détecter correctement les tableaux.

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]+)\]/, '').toLowerCase();
};

si vous voulez ensuite vérifier si un objet est dans un tableau, je voudrais aussi inclure ce code:

/**
 * 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];
    };
}

et enfin cette fonction 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
répondu Aaria Carter-Weir 2011-08-22 07:47:31