web-dev-qa-db-fra.com

Comment vérifier si un tableau inclut un objet en JavaScript?

Quel est le moyen le plus concis et le plus efficace de savoir si un tableau JavaScript contient un objet?

C’est le seul moyen que je connaisse pour le faire:

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

Existe-t-il un moyen plus efficace et plus concis d’y parvenir?

Ceci est très étroitement lié à la question de débordement de pile Le meilleur moyen de trouver un élément dans un tableau JavaScript? qui permet de rechercher des objets dans un tableau en utilisant indexOf.

3459
brad

Les navigateurs actuels ont Array#includes , ce qui fait exactement que, est largement pris en charge et comporte un polyfill pour les anciens navigateurs.

> ['joe', 'jane', 'mary'].includes('jane');
true 

Vous pouvez également utiliser Array#indexOf , qui est moins direct, mais ne nécessite pas Polyfills pour les navigateurs obsolètes.

jQuery propose $.inArray , ce qui équivaut fonctionnellement à Array#indexOf.

underscore.js , une bibliothèque d’utilitaires JavaScript, propose _.contains(list, value) , alias _.include(list, value), tous deux utilisant indexOf en interne si un tableau JavaScript est passé.

Certains autres cadres offrent des méthodes similaires:

Notez que certains frameworks l'implémentent en tant que fonction, tandis que d'autres l'ajoutent au prototype de tableau.

3894
codeape

Mise à jour: Comme @orip le mentionne dans les commentaires, le repère lié a été défini en 2008, de sorte que les résultats peuvent ne pas être pertinents pour les navigateurs modernes. Cependant, vous en aurez probablement besoin pour prendre en charge des navigateurs non-modernes et ils n’ont probablement pas été mis à jour depuis. Toujours tester pour vous-même.

Comme d'autres l'ont déjà dit, l'itération à travers le tableau est probablement la meilleure solution, mais il { a été prouvé } _ qu'une boucle décroissante while est le moyen le plus rapide d'itérer en JavaScript. Donc, vous voudrez peut-être réécrire votre code comme suit:

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

Bien entendu, vous pouvez également étendre le prototype Array:

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

Et maintenant, vous pouvez simplement utiliser les éléments suivants:

alert([1, 2, 3].contains(2)); // => true
alert([1, 2, 3].contains('2')); // => false
374
Damir Zekić

indexOf peut-être, mais c'est une "extension JavaScript à la norme ECMA-262; en tant que telle, elle peut ne pas être présente dans d'autres implémentations de la norme."

Exemple:

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

AFAICS Microsoft n'offre pas une sorte d'alternative à cela, mais vous pouvez ajouter une fonctionnalité similaire aux tableaux dans Internet Explorer (et d'autres navigateurs ne prenant pas en charge indexOf) si vous le souhaitez. un la recherche rapide sur Google révèle } _ (par exemple, celui-ci ).

169
cic

ECMAScript 7 introduit Array.prototype.includes .

Il peut être utilisé comme ceci:

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

Il accepte également un deuxième argument optionnel fromIndex:

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

Contrairement à indexOf, qui utilise Strict Equality Comparison , includes compare à l'aide de SameValueZero algorithme d'égalité. Cela signifie que vous pouvez détecter si un tableau inclut une NaN:

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

De même, contrairement à indexOf, includes n'ignore pas les index manquants:

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

Actuellement, il s'agit encore d'un brouillon, mais vous pouvez utiliser polyfilled pour le faire fonctionner sur tous les navigateurs.

140
Oriol

b est la valeur et a est le tableau. Il retourne true ou false:

function(a, b) {
    return a.indexOf(b) != -1
}
100
william malo

Voici une implémentation de JavaScript 1.6 compatible avec Array.indexOf:

if (!Array.indexOf) {
    Array.indexOf = [].indexOf ?
        function(arr, obj, from) {
            return arr.indexOf(obj, from);
        } :
        function(arr, obj, from) { // (for IE6)
            var l = arr.length,
                i = from ? parseInt((1 * from) + (from < 0 ? l : 0), 10) : 0;
            i = i < 0 ? 0 : i;
            for (; i < l; i++) {
                if (i in arr && arr[i] === obj) {
                    return i;
                }
            }
            return -1;
        };
}
71
Már Örlygsson

Les premières réponses supposent des types primitifs, mais si vous voulez savoir si un tableau contient un objet avec un trait, Array.prototype.some () est une solution très élégante:

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

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

La bonne chose à ce sujet est que l’itération est abandonnée une fois que l’élément est trouvé, ainsi les cycles d’itération inutiles sont sauvegardés.

De plus, il s’intègre parfaitement dans une instruction if car il renvoie un booléen:

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

* Comme l'a souligné jamess dans le commentaire, à compter d'aujourd'hui, septembre 2018, Array.prototype.some() est entièrement pris en charge: Tableau de support caniuse.com

66
Michael

Utilisation:

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

// Usage
if(isInArray(my_array, "my_value"))
{
    //...
}
50
Matías Cánepa

L'extension de l'objet Array de JavaScript est une très mauvaise idée, car vous introduisez de nouvelles propriétés (vos méthodes personnalisées) dans les boucles for-in, qui risquent de casser les scripts existants. Il y a quelques années, les auteurs de la bibliothèque Prototype ont dû repenser leur implémentation pour supprimer ce genre de choses.

Si vous n'avez pas à vous soucier de la compatibilité avec les autres scripts JavaScript en cours d'exécution sur votre page, n'hésitez pas, sinon, je vous conseillerais la solution de fonction autonome la plus délicate, mais la plus sûre.

42
Mason Houtz

Réfléchissez une seconde, si vous passez cet appel plusieurs fois, son utilisation est beaucoup plus efficace. un tableau associatif une carte pour faire des recherches en utilisant une fonction de hachage.

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

27
MattMcKnight

Bon mot:

function contains(arr, x) {
    return arr.filter(function(elem) { return elem == x }).length > 0;
}
24
AlonL

J'utilise les éléments suivants:

Array.prototype.contains = function (v) {
    return this.indexOf(v) > -1;
}

var a = [ 'foo', 'bar' ];

a.contains('foo'); // true
a.contains('fox'); // false
22
Eduardo Cuomo
function contains(a, obj) {
    return a.some(function(element){return element == obj;})
}

Array.prototype.some () a été ajouté à la norme ECMA-262 dans la 5e édition

19
dansalmo

Une bidirectionnelle, espérons-le, plus rapide indexOf/lastIndexOf alternative

2015

Alors que la nouvelle méthode includes est très agréable, le support est essentiellement nul pour le moment.

Cela faisait longtemps que je pensais au moyen de remplacer les fonctions lentes indexOf/lastIndexOf.

Un moyen performant a déjà été trouvé, en regardant les principales réponses. Parmi ceux-ci, j'ai choisi la fonction contains publiée par @Damir Zekic, qui devrait être la plus rapide. Mais il indique également que les repères datent de 2008 et sont donc dépassés.

Je préfère également while à for, mais pour une raison non précise, j'ai fini d'écrire la fonction avec une boucle for. Cela pourrait également être fait avec un while --.

J'étais curieux de savoir si l'itération était beaucoup plus lente si je vérifiais les deux côtés du tableau en le faisant. Apparemment non, et donc cette fonction est environ deux fois plus rapide que les plus votés. Évidemment, c'est aussi plus rapide que le natif. Ceci dans un environnement réel, où vous ne savez jamais si la valeur que vous recherchez se trouve au début ou à la fin du tableau.

Quand vous savez que vous venez de pousser un tableau avec une valeur, lastIndexOf reste probablement la meilleure solution, mais si vous devez parcourir de grands tableaux et que le résultat risque d'être omniprésent, il peut s'agir d'une solution solide pour accélérer les choses.

Index bidirectionnel/lastIndexOf

function bidirectionalIndexOf(a, b, c, d, e){
  for(c=a.length,d=c*1; c--; ){
    if(a[c]==b) return c; //or this[c]===b
    if(a[e=d-1-c]==b) return e; //or a[e=d-1-c]===b
  }
  return -1
}

//Usage
bidirectionalIndexOf(array,'value');

Test de performance

http://jsperf.com/bidirectionalindexof

Comme test, j'ai créé un tableau avec 100 000 entrées.

Trois requêtes: au début, au milieu et à la fin du tableau.

J'espère que vous trouvez également cela intéressant et testez les performances.

Remarque: Comme vous pouvez le constater, j'ai légèrement modifié la fonction contains pour refléter la sortie indexOf & lastIndexOf (donc, fondamentalement, true avec index et false avec -1). Cela ne devrait pas nuire.

La variante du prototype de tableau

Object.defineProperty(Array.prototype,'bidirectionalIndexOf',{value:function(b,c,d,e){
  for(c=this.length,d=c*1; c--; ){
    if(this[c]==b) return c; //or this[c]===b
    if(this[e=d-1-c] == b) return e; //or this[e=d-1-c]===b
  }
  return -1
},writable:false, enumerable:false});

// Usage
array.bidirectionalIndexOf('value');

La fonction peut également être facilement modifiée pour renvoyer true ou false, voire l’objet, la chaîne ou quoi que ce soit.

Et voici la variante while:

function bidirectionalIndexOf(a, b, c, d){
  c=a.length; d=c-1;
  while(c--){
    if(b===a[c]) return c;
    if(b===a[d-c]) return d-c;
  }
  return c
}

// Usage
bidirectionalIndexOf(array,'value');

Comment est-ce possible?

Je pense que le calcul simple pour obtenir l'index reflété dans un tableau est si simple qu'il est deux fois plus rapide que de faire une itération de boucle réelle.

Voici un exemple complexe effectuant trois vérifications par itération, mais cela n’est possible qu’avec un calcul plus long qui entraîne le ralentissement du code.

http://jsperf.com/bidirectionalindexof/2

14
cocco

Si vous vérifiez de manière répétée l'existence d'un objet dans un tableau, vous devriez peut-être examiner

  1. Garder le tableau trié à tout moment en faisant insertion tri dans votre tableau (placez les nouveaux objets au bon endroit) 
  2. Faire des objets de mise à jour en tant qu'opération de suppression + trié et
  3. Utilisez un recherche binaire lookup dans votre contains(a, obj).
12
Ztyx

Nous utilisons cet extrait (fonctionne avec des objets, des tableaux, des chaînes):

/*
 * @function
 * @name Object.prototype.inArray
 * @description Extend Object prototype within inArray function
 *
 * @param {mix}    needle       - Search-able needle
 * @param {bool}   searchInKey  - Search needle in keys?
 *
 */
Object.defineProperty(Object.prototype, 'inArray',{
    value: function(needle, searchInKey){

        var object = this;

        if( Object.prototype.toString.call(needle) === '[object Object]' || 
            Object.prototype.toString.call(needle) === '[object Array]'){
            needle = JSON.stringify(needle);
        }

        return Object.keys(object).some(function(key){

            var value = object[key];

            if( Object.prototype.toString.call(value) === '[object Object]' || 
                Object.prototype.toString.call(value) === '[object Array]'){
                value = JSON.stringify(value);
            }

            if(searchInKey){
                if(value === needle || key === needle){
                return true;
                }
            }else{
                if(value === needle){
                    return true;
                }
            }
        });
    },
    writable: true,
    configurable: true,
    enumerable: false
});

Utilisation:

var a = {one: "first", two: "second", foo: {three: "third"}};
a.inArray("first");          //true
a.inArray("foo");            //false
a.inArray("foo", true);      //true - search by keys
a.inArray({three: "third"}); //true

var b = ["one", "two", "three", "four", {foo: 'val'}];
b.inArray("one");         //true
b.inArray('foo');         //false
b.inArray({foo: 'val'})   //true
b.inArray("{foo: 'val'}") //false

var c = "String";
c.inArray("S");        //true
c.inArray("s");        //false
c.inArray("2", true);  //true
c.inArray("20", true); //false
12
dr.dimitru
function inArray(elem,array)
{
    var len = array.length;
    for(var i = 0 ; i < len;i++)
    {
        if(array[i] == elem){return i;}
    }
    return -1;
} 

Renvoie l'index d'un tableau s'il est trouvé ou -1 s'il n'est pas trouvé.

12
LmC

Si vous utilisez JavaScript 1.6 ou version ultérieure (Firefox 1.5 ou version ultérieure), vous pouvez utiliser Array.indexOf . Sinon, je pense que vous allez vous retrouver avec quelque chose de similaire à votre code d'origine.

10
Andru Luvisi

Utilisez la fonction some de lodash.

Il est concis, précis et offre un excellent support multi-plateformes.

La réponse acceptée ne répond même pas aux exigences.

Requis: Recommandez le moyen le plus concis et le plus efficace de savoir si un tableau JavaScript contient un objet.

Réponse acceptée:

$.inArray({'b': 2}, [{'a': 1}, {'b': 2}])
> -1

Ma recommandation:

_.some([{'a': 1}, {'b': 2}], {'b': 2})
> true

Remarques: 

$ .inArray fonctionne bien pour déterminer si une valeur scalaire existe dans un tableau de scalaires ...

$.inArray(2, [1,2])
> 1

... mais la question demande clairement un moyen efficace de déterminer si un objet est contenu dans un tableau.

Pour gérer les scalaires et les objets, vous pouvez faire ceci:

(_.isObject(item)) ? _.some(ary, item) : (_.indexOf(ary, item) > -1)
9
l3x

Solution qui fonctionne dans tous les navigateurs modernes:

function contains(arr, obj) {
  const stringifiedObj = JSON.stringify(obj); // Cache our object to not call `JSON.stringify` on every iteration
  return arr.some(item => JSON.stringify(item) === stringifiedObj);
}

Usage:

contains([{a: 1}, {a: 2}], {a: 1}); // true

Solution IE6 +:

function contains(arr, obj) {
  var stringifiedObj = JSON.stringify(obj)
  return arr.some(function (item) {
    return JSON.stringify(item) === stringifiedObj;
  });
}

// .some polyfill, not needed for IE9+
if (!('some' in Array.prototype)) {
  Array.prototype.some = function (tester, that /*opt*/) {
    for (var i = 0, n = this.length; i < n; i++) {
      if (i in this && tester.call(that, this[i], i, this)) return true;
    } return false;
  };
}

Usage:

contains([{a: 1}, {a: 2}], {a: 1}); // true

Pourquoi utiliser JSON.stringify?

Array.indexOf et Array.includes (ainsi que la plupart des réponses ici) ne comparent que par référence et non par valeur.

[{a: 1}, {a: 2}].includes({a: 1});
// false, because {a: 1} is a new object

Prime

ES6 one-liner non optimisé:

[{a: 1}, {a: 2}].some(item => JSON.stringify(item) === JSON.stringify({a: 1));
// true

Remarque: La comparaison d'objets par valeur fonctionnera mieux si les clés sont dans le même ordre. Par sécurité, vous pouvez donc trier les clés d'abord avec un package tel que celui-ci: https://www.npmjs.com/ package/sort-keys


Mise à jour de la fonction contains avec une optimisation perf. Merci itinance pour le signaler.

9
Igor Barbashin

array.indexOf(x)!=-1 est le moyen le plus concis de le faire (et est supporté par les navigateurs autres qu'Internet Explorer depuis plus de 10 ans ...), mais ce n'est pas O (1), mais plutôt O (N), ce qui est terrible. Si votre tableau ne changera pas, vous pouvez convertir votre tableau en table de hachage, puis faites table[x]!==undefined ou ===undefined:

Array.prototype.toTable = function() {
    var t = {};
    this.forEach(function(x){t[x]=true});
    return t;
}

Démo:

var toRemove = [2,4].toTable();
[1,2,3,4,5].filter(function(x){return toRemove[x]===undefined})

(Malheureusement, bien que vous puissiez créer un Array.prototype.contains pour "geler" un tableau et stocker une table de hachage dans this._cache sur deux lignes, cela donnerait des résultats erronés si vous choisissez de modifier votre tableau ultérieurement. JavaScript ne possède pas de points d'ancrage suffisants pour laissez-vous garder cet état, contrairement à Python par exemple.)

8
ninjagecko

ECMAScript 6 a une proposition élégante sur find.

La méthode find exécute la fonction de rappel une fois pour chaque élément présent dans le tableau jusqu'à ce qu'il en trouve un où le rappel renvoie un vrai valeur. Si un tel élément est trouvé, find renvoie immédiatement la valeur de cet élément. Sinon, find renvoie undefined. callback est invoqué uniquement pour les index du tableau ayant des valeurs assignées; il n'est pas appelé pour les index qui ont été supprimés ou qui n'ont jamais été assigné des valeurs.

Voici la documentation MDN à ce sujet.

La fonctionnalité de recherche fonctionne comme ceci.

function isPrime(element, index, array) {
    var start = 2;
    while (start <= Math.sqrt(element)) {
        if (element % start++ < 1) return false;
    }
    return (element > 1);
}

console.log( [4, 6, 8, 12].find(isPrime) ); // Undefined, not found
console.log( [4, 5, 8, 12].find(isPrime) ); // 5

Vous pouvez utiliser ceci dans ECMAScript 5 et inférieur pour en définissant la fonction .

if (!Array.prototype.find) {
  Object.defineProperty(Array.prototype, 'find', {
    enumerable: false,
    configurable: true,
    writable: true,
    value: function(predicate) {
      if (this == null) {
        throw new TypeError('Array.prototype.find called on null or undefined');
      }
      if (typeof predicate !== 'function') {
        throw new TypeError('predicate must be a function');
      }
      var list = Object(this);
      var length = list.length >>> 0;
      var thisArg = arguments[1];
      var value;

      for (var i = 0; i < length; i++) {
        if (i in list) {
          value = list[i];
          if (predicate.call(thisArg, value, i, list)) {
            return value;
          }
        }
      }
      return undefined;
    }
  });
}
7
Pradeep Mahdevu

Utilisation:

var myArray = ['yellow', 'orange', 'red'] ;

alert(!!~myArray.indexOf('red')); //true

Démo

Pour savoir exactement ce que la tilde~ fait à ce stade, reportez-vous à cette question Que fait un tilde quand il précède une expression?.

6
Mina Gabriel

Voici comment Le prototype le fait :

/**
 *  Array#indexOf(item[, offset = 0]) -> Number
 *  - item (?): A value that may or may not be in the array.
 *  - offset (Number): The number of initial items to skip before beginning the
 *      search.
 *
 *  Returns the position of the first occurrence of `item` within the array &mdash; or
 *  `-1` if `item` doesn't exist in the array.
**/
function indexOf(item, i) {
  i || (i = 0);
  var length = this.length;
  if (i < 0) i = length + i;
  for (; i < length; i++)
    if (this[i] === item) return i;
  return -1;
}

Voir aussi ici pour savoir comment ils l’accrochent.

4
Ken

Vous pouvez également utiliser cette astuce:

var arrayContains = function(object) {
  return (serverList.filter(function(currentObject) {
    if (currentObject === object) {
      return currentObject
    }
    else {
      return false;
    }
  }).length > 0) ? true : false
}
3
user2724028

OK, vous pouvez simplement optimiser votre code pour obtenir le résultat! 

Il y a de nombreuses façons de le faire qui sont plus propres et meilleures, mais je voulais juste obtenir votre modèle et l'appliquer à l'aide de JSON.stringify, faites simplement une chose comme celle-ci dans votre cas:

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

Utilisation:

Array.prototype.contains = function(x){
  var retVal = -1;

  // x is a primitive type
  if(["string","number"].indexOf(typeof x)>=0 ){ retVal = this.indexOf(x);}

  // x is a function
  else if(typeof x =="function") for(var ix in this){
    if((this[ix]+"")==(x+"")) retVal = ix;
  }

  //x is an object...
  else {
    var sx=JSON.stringify(x);
    for(var ix in this){
      if(typeof this[ix] =="object" && JSON.stringify(this[ix])==sx) retVal = ix;
    }
  }

  //Return False if -1 else number if numeric otherwise string
  return (retVal === -1)?false : ( isNaN(+retVal) ? retVal : +retVal);
}

Je sais que ce n'est pas la meilleure façon de faire, mais comme il n'y a pas de moyen IComparable natif d'interagir entre les objets, je suppose que c'est aussi proche que possible de comparer deux entités dans un tableau. Également, étendre un objet Array peut ne pas être une bonne chose à faire, mais parfois ça va (si vous en êtes conscient et le compromis).

3
Carlos A

On peut utiliser Set qui a la méthode "has ()":

function contains(arr, obj) {
  var proxy = new Set(arr);
  if (proxy.has(obj))
    return true;
  else
    return false;
}

var arr = ['Happy', 'New', 'Year'];
console.log(contains(arr, 'Happy'));
3
rlib
  1. Utilisez soit Array.indexOf(Object)
  2. Avec ECMA 7, vous pouvez utiliser la fonction Array.includes(Object)
  3. Avec ECMA 6, vous pouvez utiliser Array.find(FunctionName)FunctionName est une fonction définie par l'utilisateur pour rechercher l'objet dans le tableau.

    J'espère que cela t'aides!

2
kg11

Comme d'autres l'ont mentionné, vous pouvez utiliser Array.indexOf, mais il n'est pas disponible dans tous les navigateurs. Voici le code de https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf pour le rendre identique dans les navigateurs plus anciens.

indexOf est un ajout récent à la norme ECMA-262; en tant que tel, il peut ne pas être présent dans tous les navigateurs. Vous pouvez contourner ce problème en insérant le code suivant au début de vos scripts, permettant l’utilisation de indexOf dans les implémentations qui ne le supportent pas nativement. Ce L'algorithme est exactement celui spécifié dans ECMA-262, 5ème édition, en supposant que Object, TypeError, Number, Math.floor, Math.abs et Math.max ont leur valeur d'origine.

if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
        "use strict";
        if (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 > 1) {
            n = Number(arguments[1]);
            if (n != n) { // shortcut for verifying if it's NaN
                n = 0;
            } else if (n != 0 && n != Infinity && n != -Infinity) {
                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
Simon_Weaver

Surpris que la dernière syntaxe de cette question n’ait toujours pas été ajoutée, en ajoutant mes 2 centimes.

Disons que nous avons un tableau d'objets arrObj et que nous voulons y rechercher obj.

Array.prototype. indexOf -> (renvoie index ou -1 ) est généralement utilisé pour rechercher l'index d'un élément dans un tableau. Ceci peut également être utilisé pour rechercher un objet mais ne fonctionne que si vous passez une référence au même objet.

let obj = { name: 'Sumer', age: 36 };
let arrObj = [obj, { name: 'Kishor', age: 46 }, { name: 'Rupen', age: 26 }];


console.log(arrObj.indexOf(obj));// 0
console.log(arrObj.indexOf({ name: 'Sumer', age: 36 })); //-1

console.log([1, 3, 5, 2].indexOf(2)); //3

Array.prototype. inclut -> (retourne vrai ou faux )

console.log(arrObj.includes(obj));  //true
console.log(arrObj.includes({ name: 'Sumer', age: 36 })); //false

console.log([1, 3, 5, 2].includes(2)); //true

Array.prototype. find -> (prend un callback, retourne en premier value/object qui renvoie true dans CB).

console.log(arrObj.find(e => e.age > 40));  //{ name: 'Kishor', age: 46 }
console.log(arrObj.find(e => e.age > 40)); //{ name: 'Kishor', age: 46 }

console.log([1, 3, 5, 2].find(e => e > 2)); //3

Array.prototype. findIndex -> (prend le rappel, retourne index de la première valeur/objet qui retourne vrai dans CB).

console.log(arrObj.findIndex(e => e.age > 40));  //1
console.log(arrObj.findIndex(e => e.age > 40)); //1

console.log([1, 3, 5, 2].findIndex(e => e > 2)); //1

Puisque find et findIndex acceptent un rappel, nous pouvons extraire n'importe quel objet (même si nous n'avons pas la référence) d'un tableau en définissant de manière créative la vraie condition.

2
Sumer

Ce n’est certes pas le meilleur, mais j’étais simplement créatif et j’ajoutais du répertoire.

Ne pas utiliser ce

Object.defineProperty(Array.prototype, 'exists', {
  value: function(element, index) {

    var index = index || 0

    return index === this.length ? -1 : this[index] === element ? index : this.exists(element, ++index)
  }
})


// Outputs 1
console.log(['one', 'two'].exists('two'));

// Outputs -1
console.log(['one', 'two'].exists('three'));

console.log(['one', 'two', 'three', 'four'].exists('four'));

2
sqram

J'ai regardé à travers les réponses soumises et j'ai compris qu'elles ne s'appliquent que si vous recherchez l'objet via une référence. Une recherche linéaire simple avec comparaison d'objet de référence. 

Mais disons que vous n'avez pas la référence à un objet, comment allez-vous trouver le bon objet dans le tableau? Vous devrez aller linéairement et profondément comparer avec chaque objet. Imaginez si la liste est trop longue et que les objets qu'elle contient sont très grands et contiennent de gros morceaux de texte. Les performances chutent considérablement avec le nombre et la taille des éléments du tableau.

Vous pouvez stringifier les objets et les mettre dans la table de hachage native, mais vous aurez alors la redondance des données en vous rappelant que ces clés sont conservées car JavaScript les conserve pour 'for i in obj', et vous voulez seulement vérifier si l'objet existe ou non, c'est-à-dire , vous avez la clé.

Je pensais à cela pendant un certain temps en construisant un validateur JSON Schema et j'ai conçu un simple wrapper pour la table de hachage native, similaire à la mise en œuvre unique de la table de hachage, avec quelques exceptions d'optimisation que j'ai laissées à la table de hachage native. Il ne nécessite que des analyses comparatives des performances…. Tous les détails et le code sont disponibles sur mon blog: http://stamat.wordpress.com/javascript-quickly-find-very-large-objects-in-a -large-array/ Je publierai bientôt les résultats des tests. 

La solution complète fonctionne comme ceci:

var a = {'a':1,
 'b':{'c':[1,2,[3,45],4,5],
 'd':{'q':1, 'b':{'q':1, 'b':8},'c':4},
 'u':'lol'},
 'e':2};

 var b = {'a':1, 
 'b':{'c':[2,3,[1]],
 'd':{'q':3,'b':{'b':3}}},
 'e':2};

 var c = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.";

 var hc = new HashCache([{a:3, b:2, c:5}, {a:15, b:2, c:'foo'}]); //init

 hc.put({a:1, b:1});
 hc.put({b:1, a:1});
 hc.put(true);
 hc.put('true');
 hc.put(a);
 hc.put(c);
 hc.put(d);
 console.log(hc.exists('true'));
 console.log(hc.exists(a));
 console.log(hc.exists(c));
 console.log(hc.exists({b:1, a:1}));
 hc.remove(a);
 console.log(hc.exists(c));
1
stamat

Si vous travaillez avec ES6 Vous pouvez utiliser un ensemble:

function arrayHas( array, element ) {
    const s = new Set(array);
    return s.has(element)
}

Cela devrait être plus performant que n'importe quelle autre méthode

1
Neil Girardi

Ou cette solution:

Array.prototype.includes = function (object) {
  return !!+~this.indexOf(object);
};
1
Tefa

Une chose similaire: trouve le premier élément par un "search lambda":

Array.prototype.find = function(search_lambda) {
  return this[this.map(search_lambda).indexOf(true)];
};

Usage:

[1,3,4,5,8,3,5].find(function(item) { return item % 2 == 0 })
=> 4

Même chose en coffeescript:

Array.prototype.find = (search_lambda) -> @[@map(search_lambda).indexOf(true)]
1
Andy Rohr

Je travaillais sur un projet pour lequel j'avais besoin d'une fonctionnalité telle que python set qui supprime toutes les valeurs en double et renvoie une nouvelle liste. J'ai donc écrit cette fonction qui pourrait être utile à quelqu'un.

function set(arr) {
    var res = [];
    for (var i = 0; i < arr.length; i++) {
        if (res.indexOf(arr[i]) === -1) {
            res.Push(arr[i]);
        }
    }
    return res;
}
1
Jeeva

J'ai recommandé d'utiliser la bibliothèque de soulignement parce qu'elle renvoie la valeur et est prise en charge par tous les navigateurs. 

underscorejs

 var findValue = _.find(array, function(item) {
    return item.id == obj.id;
 });
1
Durgpal Singh

Il a un paramètre: un tableau de nombres d'objets. Chaque objet du tableau a deux propriétés entières désignées par x et y. La fonction doit renvoyer un nombre de tous ces objets du tableau satisfaisant numbers.x == numbers.y

var numbers = [ { x: 1, y: 1 },
                 { x: 2, y: 3 },
                 { x: 3, y: 3 },
                 { x: 3, y: 4 },
                 { x: 4, y: 5 } ];
    count = 0; 
var n = numbers.length;
for (var i =0;i<n;i++)
{
  if(numbers[i].x==numbers[i].y)
  {count+=1;}
}

alert(count);
1
Mitul Panchal

Utiliser idnexOf () est une bonne solution, mais vous devriez masquer la fonction d'indexation intégrée d'implémentation qui renvoie -1 avec l'opérateur ~: 

function include(arr,obj) { 
    return !!(~arr.indexOf(obj)); 
} 
0
KRRySS

En plus de ce que d'autres ont dit, si vous n'avez pas de référence à l'objet que vous voulez chercher dans le tableau, vous pouvez faire quelque chose comme ça.

let array = [1, 2, 3, 4, {"key": "value"}];

array.some((element) => JSON.stringify(element) === JSON.stringify({"key": "value"})) // true

array.some((element) => JSON.stringify(element) === JSON.stringify({})) // true

Array.some renvoie true si un élément correspond à la condition donnée et false si aucun des éléments ne correspond à la condition donnée.

0
Nitesh Ranjan

Utilisation incluant la fonction javascript in-build

var optval = [];

optval.Push('A');    
optval.Push('B');    
optval.Push('C');

Nous pouvons rechercher la chaîne A dans le tableau javascript comme suit:

optval.includes('A') // =====> return true
0
Rajeev Ranjan

Solution simple: ES6 Features " includes " method

let arr = [1, 2, 3, 2, 3, 2, 3, 4];

  arr.includes(2) // true

  arr.includes(93) // false
0
ngCourse
function countArray(originalArray) {

    var compressed = [];
    // make a copy of the input array
    var copyArray = originalArray.slice(0);

    // first loop goes over every element
    for (var i = 0; i < originalArray.length; i++) {

        var count = 0;  
        // loop over every element in the copy and see if it's the same
        for (var w = 0; w < copyArray.length; w++) {
            if (originalArray[i] == copyArray[w]) {
                // increase amount of times duplicate is found
                count++;
                // sets item to undefined
                delete copyArray[w];
            }
        }

        if (count > 0) {
            var a = new Object();
            a.value = originalArray[i];
            a.count = count;
            compressed.Push(a);
        }
    }

    return compressed;
};

// It should go something like this:

var testArray = new Array("dog", "dog", "cat", "buffalo", "wolf", "cat", "tiger", "cat");
var newArray = countArray(testArray);
console.log(newArray);
0
Sanjay Magar