Vraag Hoe controleer ik of een array een object bevat in JavaScript?


Wat is de meest beknopte en efficiënte manier om erachter te komen of een JavaScript-array een object bevat?

Dit is de enige manier die ik weet om het te doen:

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

Is er een betere en meer beknopte manier om dit te bereiken?

Dit hangt nauw samen met de vraag Stack Overflow De beste manier om een ​​item in een JavaScript-array te vinden? die adressen zoeken in een array met behulp van indexOf.


3217
2017-10-25 22:14


oorsprong


antwoorden:


Huidige browsers hebben Array#includes, wat doet precies dat, wordt breed ondersteund, en heeft een polyfill voor oudere browsers.

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

Je kan ook gebruiken Array#indexOf, wat minder direct is, maar waarvoor Polyfills niet vereist is voor verouderde browsers.

jQuery biedt $.inArray, dat functioneel equivalent is aan Array#indexOf.

underscore.js, een JavaScript-bibliotheek, aanbiedingen _.contains(list, value), alias _.include(list, value), die beide gebruiken index van intern als een JavaScript-array is doorgegeven.

Sommige andere frameworks bieden vergelijkbare methoden:

Merk op dat sommige frameworks dit als een functie implementeren, terwijl anderen de functie toevoegen aan het array-prototype.


3644
2017-10-25 23:10



Update: Zoals @orip vermeldt in opmerkingen, is de gekoppelde benchmark gedaan in 2008, dus resultaten zijn mogelijk niet relevant voor moderne browsers. Waarschijnlijk hebt u dit echter nodig om niet-moderne browsers te ondersteunen en deze zijn waarschijnlijk sindsdien niet meer bijgewerkt. Test het altijd voor jezelf.

Zoals anderen al hebben gezegd, is de iteratie door de array waarschijnlijk de beste manier, maar wel is bewezen dat neemt af while loop is de snelste manier om JavaScript te herhalen. Dus misschien wilt u uw code als volgt herschrijven:

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

Natuurlijk kunt u het Array-prototype ook uitbreiden:

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

En nu kunt u eenvoudig het volgende gebruiken:

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

357
2017-10-25 22:49



indexOf misschien, maar het is een "JavaScript-uitbreiding op de ECMA-262-standaard, als zodanig is het mogelijk niet aanwezig in andere implementaties van de standaard."

Voorbeeld:

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

AFAICS Microsoft doet dat niet een alternatief bieden , maar u kunt vergelijkbare functionaliteit toevoegen aan arrays in Internet Explorer (en andere browsers die dit niet ondersteunen indexOf) als je dat wilt, als een snelle Google-zoekopdracht onthult (bijvoorbeeld, deze).


156
2018-01-01 01:40



ECMAScript 7 introduceert Array.prototype.includes.

Het kan als volgt worden gebruikt:

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

Het accepteert ook een optioneel tweede argument fromIndex:

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

anders indexOf, die gebruikt Strikte gelijkheidsvergelijking, includes vergelijkt het gebruik SameValueZero gelijkheidsalgoritme. Dat betekent dat u kunt detecteren of een array een bevat NaN:

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

Ook niet zoals indexOf, includes slaat geen ontbrekende indices over:

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

Momenteel is het nog steeds een ontwerp, maar kan dat wel zijn polyfilledom het op alle browsers te laten werken.


128
2018-03-24 04:59



b is de waarde, en a is de array. Het komt terug true of false:

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

96
2017-10-27 00:38



Hier is een JavaScript 1.6 compatibel invoer van 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;
      };
}

65
2017-09-13 17:32



Gebruik:

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

// Usage
if(isInArray(my_array, "my_value"))
{
    //...
}

46
2017-08-27 16:45



JavaScript uitbreiden Array object is echt een slecht idee omdat je nieuwe eigenschappen (je eigen methoden) introduceert for-in loops die bestaande scripts kunnen doorbreken. Een paar jaar geleden schreven de auteurs van de Prototype bibliotheek moest hun bibliotheekimplementatie opnieuw ontwerpen om zoiets te verwijderen.

Als u zich geen zorgen hoeft te maken over de compatibiliteit met andere JavaScript-code die op uw pagina wordt uitgevoerd, kunt u ervoor kiezen, anders zou ik de meer lastige, maar veiligere, vrijstaande functie-oplossing aanbevelen.


38
2017-07-18 14:36



Je kunt gebruiken Array.prototype.some ()

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

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

Daar tegenover staat dat de iteratie wordt afgebroken zodra het element is gevonden, zodat onnodige iteratiecycli worden opgeslagen.

Een ding om op te merken is dat some() is niet aanwezig in alle js-versies: (van de website)

sommigen werden toegevoegd aan de ECMA-262-standaard in de 5e editie; als zodanig   mogelijk niet aanwezig in alle implementaties van de standaard

Je kunt het zonder problemen gebruiken in Node.js. Als je alle browsers wilt ondersteunen, dan is er deze polyfill (via dezelfde link):

if (!Array.prototype.some)
{
  Array.prototype.some = function(fun /*, thisArg */)
  {
    'use strict';

    if (this === void 0 || this === null)
      throw new TypeError();

    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun !== 'function')
      throw new TypeError();

    var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
    for (var i = 0; i < len; i++)
    {
      if (i in t && fun.call(thisArg, t[i], i, t))
        return true;
    }

    return false;
  };
}

33
2018-01-07 12:49



Oneliner:

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

21
2017-12-23 15:59



Als je out-of-the-box denkt, als je deze oproep vele malen maakt, is het veel efficiënter in gebruik een associatieve array een kaart om lookups te doen met behulp van een hash-functie.

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


21
2018-06-15 01:15