Déterminer si un tableau contient une valeur [dupliquer]

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

je dois déterminer si une valeur existe dans un tableau.

j'utilise la fonction suivante:

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

la fonction ci-dessus renvoie toujours false.

les valeurs du tableau et l'appel de fonction sont comme ci-dessous:

arrValues = ["Sam","Great", "Sample", "High"]
alert(arrValues.contains("Sam"));
1178
demandé sur zx8754 2009-07-25 12:18:57
la source

18 ответов

var contains = function(needle) {
    // Per spec, the way to identify NaN is that it is not equal to itself
    var findNaN = needle !== needle;
    var indexOf;

    if(!findNaN && typeof Array.prototype.indexOf === 'function') {
        indexOf = Array.prototype.indexOf;
    } else {
        indexOf = function(needle) {
            var i = -1, index = -1;

            for(i = 0; i < this.length; i++) {
                var item = this[i];

                if((findNaN && item !== item) || item === needle) {
                    index = i;
                    break;
                }
            }

            return index;
        };
    }

    return indexOf.call(this, needle) > -1;
};

Vous pouvez l'utiliser comme ceci:

var myArray = [0,1,2],
    needle = 1,
    index = contains.call(myArray, needle); // true

CodePen la validation/l'utilisation de la

958
répondu eyelidlessness 2016-01-05 05:46:56
la source

jQuery a une fonction utilitaire pour ceci:

$.inArray(value, array)

Renvoie l'indice de la value dans array . Renvoie -1 si array ne contient pas value .

Voir aussi Comment puis-je vérifier si un tableau inclut un objet en JavaScript?

940
répondu codeape 2017-05-23 15:18:26
la source

c'est généralement à cela que sert la méthode indexOf (). Vous diriez:

return arrValues.indexOf('Sam') > -1
772
répondu Gabriel Hurley 2016-03-04 22:23:36
la source
"151980920 Tableau.prototype.y compris ()

en ES2016, il y a Array.prototype.includes() .

la méthode includes() détermine si un tableau comprend un certain élément, en retournant true ou false selon le cas.

exemple

["Sam", "Great", "Sample", "High"].includes("Sam"); // true

Support

selon kangax et MDN , les plates-formes suivantes sont prises en charge:

  • Chrome 47
  • Edge 14
  • Firefox 43
  • Opéra 34
  • Safari 9
  • Nœud 6

peut être étendu en utilisant Babel (en utilisant babel-polyfill ) ou core-js . MDN fournit un polyfill :

if (![].includes) {
  Array.prototype.includes = function(searchElement /*, fromIndex*/ ) {
    'use strict';
    var O = Object(this);
    var len = parseInt(O.length) || 0;
    if (len === 0) {
      return false;
    }
    var n = parseInt(arguments[1]) || 0;
    var k;
    if (n >= 0) {
      k = n;
    } else {
      k = len + n;
      if (k < 0) {k = 0;}
    }
    var currentElement;
    while (k < len) {
      currentElement = O[k];
      if (searchElement === currentElement ||
         (searchElement !== searchElement && currentElement !== currentElement)) {
        return true;
      }
      k++;
    }
    return false;
  };
}
271
répondu Dale 2017-09-24 12:13:22
la source

il est presque toujours plus sûr d'utiliser une bibliothèque comme lodash simplement en raison de tous les problèmes avec compatibilité et l'efficacité du navigateur.

efficacité parce que vous pouvez être assuré qu'à tout moment, une bibliothèque très populaire comme underscore aura la méthode la plus efficace pour accomplir une fonction utilitaire comme celle-ci.

_.includes([1, 2, 3], 3); // returns true

si vous êtes préoccupé par le volume qui est ajouté à votre application en incluant toute la bibliothèque, sachez que vous pouvez inclure la fonctionnalité séparément:

var includes = require('lodash/collections/includes');

remarque: avec des versions plus anciennes de lodash, c'était _.contains() plutôt que _.includes() .

117
répondu ncabral 2017-11-04 20:39:20
la source

tl; dr

function includes(k) {
  for(var i=0; i < this.length; i++){
    if( this[i] === k || ( this[i] !== this[i] && k !== k ) ){
      return true;
    }
  }
  return false;
}

exemple

function includes(k) {
  for(var i=0; i < this.length; i++){
    if( this[i] === k || ( this[i] !== this[i] && k !== k ) ){
      return true;
    }
  }
  return false;
}

function log(msg){
  $('#out').append('<div>' + msg + '</div>');  
}

var arr = [1, "2", NaN, true];
arr.includes = includes;

log('var arr = [1, "2", NaN, true];');
log('<br/>');
log('arr.includes(1): ' + arr.includes(1));
log('arr.includes(2): ' + arr.includes(2));
log('arr.includes("2"): ' + arr.includes("2"));
log('arr.includes(NaN): ' + arr.includes(NaN));
log('arr.includes(true): ' + arr.includes(true));
log('arr.includes(false): ' + arr.includes(false));
#out{
  font-family:monospace;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id=out></div>

Plus Longue Réponse

je sais que cette question n'est pas vraiment de savoir s'il faut étendre ou non les objets intégrés, mais la tentative de L'OP et les commentaires sur cette réponse mettent en évidence ce débat. Mon commentaire du 12 Février 13 cite un article qui décrit ce débat vraiment bien, mais ce lien cassé et je ne peux pas éditer le commentaire original parce que trop de temps a passé, donc je l'inclus ici .

si vous cherchez à étendre l'Objet intégré Array avec une méthode contains , probablement la meilleure et la plus responsable façon de le faire serait d'utiliser ce polyfill de MDN . (Voir aussi cette section du MDN article sur l'héritage prototypique, qui explique que " la seule bonne raison pour étendre un prototype intégré est de rétroporter les caractéristiques des nouveaux moteurs JavaScript, par exemple Array.forEach, etc." )

if (!Array.prototype.includes) {
  Array.prototype.includes = function(searchElement /*, fromIndex*/ ) {
    'use strict';
    var O = Object(this);
    var len = parseInt(O.length) || 0;
    if (len === 0) {
      return false;
    }
    var n = parseInt(arguments[1]) || 0;
    var k;
    if (n >= 0) {
      k = n;
    } else {
      k = len + n;
      if (k < 0) {k = 0;}
    }
    var currentElement;
    while (k < len) {
      currentElement = O[k];
      if (searchElement === currentElement ||
         (searchElement !== searchElement && currentElement !== currentElement)) {
        return true;
      }
      k++;
    }
    return false;
  };
}

vous ne voulez pas l'égalité stricte, ou vous voulez choisir?

function includes(k, strict) {
  strict = strict !== false; // default is true
  // strict = !!strict; // default is false
  for(var i=0; i < this.length; i++){
    if( (this[i] === k && strict) || 
        (this[i] == k && !strict) ||
        (this[i] !== this[i] && k !== k)
    ) {
      return true;
    }
  }
  return false;
}
46
répondu Trevor 2016-04-15 19:55:54
la source

depuis ECMAScript6, on peut utiliser Set :

var myArray = ['A', 'B', 'C'];
var mySet = new Set(myArray);
var hasB = mySet.has('B'); // true
var hasZ = mySet.has('Z'); // false
34
répondu Nicolas 2017-10-13 04:40:05
la source

ma petite contribution:

function isInArray(array, search)
{
    return array.indexOf(search) >= 0;
}

//usage
if(isInArray(my_array, "my_value"))
{
    //...
}
19
répondu Matías Cánepa 2016-02-26 02:43:55
la source

étant donné la mise en œuvre de indexOf for IE (comme décrit par eyelidlessness):

Array.prototype.contains = function(obj) {
    return this.indexOf(obj) > -1;
};
17
répondu rlovtang 2014-01-05 17:44:32
la source

si vous avez accès à ECMA 5, vous pouvez utiliser la méthode some .

MDN CERTAINS de la Méthode de Lien

arrValues = ["Sam","Great", "Sample", "High"];

function namePresent(name){
  return name === this.toString();
}
// Note:
// namePresent requires .toString() method to coerce primitive value
// i.e. String {0: "S", 1: "a", 2: "m", length: 3, [[PrimitiveValue]]: "Sam"}
// into
// "Sam"

arrValues.some(namePresent, 'Sam');
=> true;

si vous avez accès à ECMA 6, Vous pouvez utiliser la méthode includes .

MDN COMPREND Méthode Lien

arrValues = ["Sam","Great", "Sample", "High"];

arrValues.includes('Sam');
=> true;
15
répondu SoEzPz 2017-08-18 18:26:42
la source

vous pouvez utiliser _.indexde la méthode ou si vous ne voulez pas inclure tout le Underscore.bibliothèque js dans votre application, vous pouvez avoir un regard comment ils l'ont fait et extraire le code nécessaire.

    _.indexOf = function(array, item, isSorted) {
    if (array == null) return -1;
    var i = 0, l = array.length;
    if (isSorted) {
      if (typeof isSorted == 'number') {
        i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
      } else {
        i = _.sortedIndex(array, item);
        return array[i] === item ? i : -1;
      }
    }
    if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
    for (; i < l; i++) if (array[i] === item) return i;
    return -1;
  };
11
répondu Wojciech Bednarski 2013-01-11 20:54:31
la source

une Autre option serait d'utiliser Array.some ( si disponible ) de la manière suivante:

Array.prototype.contains = function(obj) {
  return this.some( function(e){ return e === obj } );
}

la fonction anonyme passée à Array.some retournera true si et seulement s'il y a un élément dans le tableau qui est identique à obj . En l'absence d'un tel élément, la fonction ne retournera pas true pour aucun des éléments du tableau, donc Array.some retournera aussi false .

9
répondu Hunan Rostomyan 2015-02-08 03:44:20
la source

Wow, il y a beaucoup de bonnes réponses à cette question.

Je n'en ai pas vu un qui adopte une approche reduce donc je vais l'ajouter dans:

var searchForValue = 'pig';

var valueIsInArray = ['horse', 'cat', 'dog'].reduce(function(previous, current){
    return previous || searchForValue === current ? true : false;
}, false);

console.log('The value "' + searchForValue + '" is in the array: ' + valueIsInArray);

voici un violon en action .

7
répondu Chris Schmitz 2016-03-07 19:20:19
la source

la réponse fournie n'a pas fonctionné pour moi, mais elle m'a donné une idée:

Array.prototype.contains = function(obj)
    {
        return (this.join(',')).indexOf(obj) > -1;
    }

il n'est pas parfait parce que les éléments qui sont les mêmes au-delà des regroupements pourraient finir par correspondre. Comme mon exemple

var c=[];
var d=[];
function a()
{
    var e = '1';
    var f = '2';
    c[0] = ['1','1'];
    c[1] = ['2','2'];
    c[2] = ['3','3'];
    d[0] = [document.getElementById('g').value,document.getElementById('h').value];

    document.getElementById('i').value = c.join(',');
    document.getElementById('j').value = d.join(',');
    document.getElementById('b').value = c.contains(d);
}

quand j'appelle cette fonction avec les champs' g 'et' h 'contenant respectivement 1 et 2, elle la trouve encore parce que la chaîne résultante de la jointure est: 1,1,2,2,3,3

Puisqu'il est douteux dans mon situation que je vais rencontrer ce type de situation, je m'en sers. J'ai pensé que je partagerais au cas où quelqu'un d'autre ne pourrait pas faire fonctionner la réponse choisie non plus.

4
répondu Kakoroat 2011-05-24 22:09:42
la source

utilisant array .carte de fonction qui exécute une fonction pour chaque valeur dans un tableau semble plus propre à moi.

Ref: Array.prototype.carte ()

cette méthode peut bien fonctionner à la fois pour les tableaux simples et pour les tableaux d'objets où vous devez voir si une clé/valeur existe dans un tableau d'objets.

function inArray(myArray,myValue){
    var inArray = false;
    myArray.map(function(key){
        if (key === myValue){
            inArray=true;
        }
    });
    return inArray;
};

var anArray = [2,4,6,8]
console.log(inArray(anArray, 8)); // returns true
console.log(inArray(anArray, 1)); // returns false

function inArrayOfObjects(myArray,myValue,objElement){
    var inArray = false;
    myArray.map(function(arrayObj){
        if (arrayObj[objElement] === myValue) {
            inArray=true;
        }
    });
    return inArray;
};

var objArray = [{id:4,value:'foo'},{id:5,value:'bar'}]
console.log(inArrayOfObjects(objArray, 4, 'id')); // returns true
console.log(inArrayOfObjects(objArray, 'bar', 'value')); // returns true
console.log(inArrayOfObjects(objArray, 1, 'id')); // returns false
4
répondu Ian Vasquez 2017-02-06 09:30:21
la source
function setFound(){   
 var l = arr.length, textBox1 = document.getElementById("text1");
    for(var i=0; i<l;i++)
    {
     if(arr[i]==searchele){
      textBox1 .value = "Found";
      return;
     }
    }
    textBox1 .value = "Not Found";
return;
}

Ce programme vérifie si l'élément est trouvé ou non. ID text1 représente l'id de textbox et searchele représente l'élément à être recherche (got fron user); si vous voulez index, utilisez la valeur i

2
répondu deeban 2015-10-06 17:04:20
la source

La solution la plus simple pour un contains , serait une fonction qui ressemble à ceci :

var contains = function (haystack, needle) {
    return !!~haystack.indexOf(needle);
}

Idéalement, vous n'en feriez pas une fonction autonome, mais une partie d'une bibliothèque d'aide:

var helper = {};

helper.array = {
    contains : function (haystack, needle) {
        return !!~haystack.indexOf(needle);
    }, 
    ...
};

maintenant, si vous arrive d'être l'un de ces gens malchanceux qui a encore besoin de soutenir IE<9 et ne peut donc pas compter sur indexOf , vous pouvez utiliser ce polyfill , que j'ai obtenu de le MDN :

if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(searchElement, fromIndex) {
    var k;
    if (this == null) {
      throw new TypeError('"this" is null or not defined');
    }
    var o = Object(this);
    var len = o.length >>> 0;
    if (len === 0) {
      return -1;
    }
    var n = +fromIndex || 0;

    if (Math.abs(n) === Infinity) {
      n = 0;
    }
    if (n >= len) {
      return -1;
    }
    k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
    while (k < len) {
      if (k in o && o[k] === searchElement) {
        return k;
      }
      k++;
    }
    return -1;
  };
}
1
répondu John Slegers 2016-02-26 03:10:44
la source

je préfère la simplicité:

var days = [1, 2, 3, 4, 5];
if ( 2 in days ) {console.log('weekday');}
-5
répondu valeri 2014-05-06 11:02:44
la source

Autres questions sur javascript arrays contains