4952 Stimmen

Wie prüfe ich, ob ein Array einen Wert in JavaScript enthält?

Wie kann man am einfachsten und effizientesten herausfinden, ob ein JavaScript-Array einen Wert enthält?

Das ist die einzige Möglichkeit, die ich kenne:

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

Gibt es eine bessere und prägnantere Möglichkeit, dies zu erreichen?

65 Stimmen

Gerade getestet: Ihr Weg ist tatsächlich der schnellste für alle Browser: jsperf.com/find-element-in-obj-vs-array/2 (abgesehen von der Vorabspeicherung von a.length in einer Variablen), während die Verwendung von indexOf (wie in $.inArray) viel langsamer ist

23 Stimmen

Viele haben geantwortet, dass die Array#indexOf ist Ihre beste Wahl hier. Aber wenn Sie etwas wollen, das korrekt in Boolean umgewandelt werden kann, verwenden Sie dies: ~[1,2,3].indexOf(4) wird 0 zurückgeben, was als falsch ausgewertet wird, während ~[1,2,3].indexOf(3) wird -3 zurückgeben, was als wahr ausgewertet wird.

13 Stimmen

~ ist nicht das, was Sie für die Konvertierung in einen Booleschen Wert verwenden wollen, dafür brauchen Sie ! . Aber in diesem Fall wollen Sie die Gleichheit mit -1 prüfen, damit die Funktion nicht endet return [1,2,3].indexOf(3) === -1; ~ nicht binär ist, wird jedes Bit des Wertes einzeln invertiert.

15voto

Igor Barbashin Punkte 813

Lösung, die in allen modernen Browsern funktioniert:

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

Verwendung:

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

IE6+ Lösung:

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

Verwendung:

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

Warum verwenden JSON.stringify ?

Array.indexOf y Array.includes (wie auch die meisten der Antworten hier) vergleichen nur nach Verweis und nicht nach Wert.

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

Bonus

Nicht optimierter ES6-Einzeiler:

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

Anmerkung: Der Vergleich von Objekten nach Wert funktioniert besser, wenn die Schlüssel in der gleichen Reihenfolge sind. Um auf Nummer sicher zu gehen, können Sie also die Schlüssel zuerst mit einem Paket wie diesem sortieren: https://www.npmjs.com/package/sort-keys


Aktualisiert die contains Funktion mit einer Perf-Optimierung. Danke itinance dass Sie darauf hingewiesen haben.

12voto

l3x Punkte 29224

Verwenden Sie lodashs einige Funktion.

Es ist übersichtlich, präzise und bietet eine hervorragende plattformübergreifende Unterstützung.

Die akzeptierte Antwort entspricht nicht einmal den Anforderungen.

Anforderungen: Empfehlen Sie den prägnantesten und effizientesten Weg, um herauszufinden, ob ein JavaScript-Array ein Objekt enthält.

Akzeptierte Antwort:

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

Meine Empfehlung:

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

Anmerkungen:

$.inArray funktioniert gut, um festzustellen, ob ein skalar Wert existiert in einem Array von Skalaren...

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

... aber die Frage fragt eindeutig nach einer effizienten Methode, um festzustellen, ob ein Objekt in einem Array enthalten ist.

Um sowohl mit Skalaren als auch mit Objekten umgehen zu können, könnte man dies tun:

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

11voto

Shiva Punkte 454

Eine einfache Lösung für diese Anforderung ist die Verwendung von find()

Wenn Sie ein Array von Objekten wie unten haben,

var users = [{id: "101", name: "Choose one..."},
{id: "102", name: "shilpa"},
{id: "103", name: "anita"},
{id: "104", name: "admin"},
{id: "105", name: "user"}];

Dann können Sie prüfen, ob das Objekt mit Ihrem Wert bereits vorhanden ist oder nicht:

let data = users.find(object => object['id'] === '104');

wenn data null ist, dann kein Admin, sonst wird das vorhandene Objekt zurückgegeben:

{id: "104", name: "admin"}

Dann können Sie den Index dieses Objekts im Array finden und das Objekt mithilfe des Codes ersetzen:

let indexToUpdate = users.indexOf(data);
let newObject = {id: "104", name: "customer"};
users[indexToUpdate] = newObject;//your new object
console.log(users);

erhalten Sie Werte wie:

[{id: "101", name: "Choose one..."},
{id: "102", name: "shilpa"},
{id: "103", name: "anita"},
{id: "104", name: "customer"},
{id: "105", name: "user"}];

10voto

Pradeep Mahdevu Punkte 7545

ECMAScript 6 hat einen eleganten Vorschlag zu find.

Die Find-Methode führt die Callback-Funktion einmal für jedes Element aus Element im Array aus, bis sie eines findet, bei dem callback den Wert true Wert zurückgibt. Wenn ein solches Element gefunden wird, gibt find sofort den Wert dieses Elements zurück. Andernfalls gibt find undefiniert zurück. callback wird wird nur für Indizes des Arrays aufgerufen, denen Werte zugewiesen sind; es wird nicht für Indizes aufgerufen, die gelöscht wurden oder denen nie Werte zugewiesen wurden.

Hier ist die MDN-Dokumentation dazu.

Die Suchfunktion funktioniert folgendermaßen.

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

Sie können dies in ECMAScript 5 und darunter verwenden, indem Sie Definition der Funktion .

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

1 Stimmen

10voto

rlib Punkte 6436

Man kann verwenden Satz die die Methode "has()" hat:

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

8 Stimmen

Ich glaube return proxy.has(obj) ist viel sauberer als zwei Zeilen mit if-else-Anweisung hier

1 Stimmen

function contains(arr, obj) { return new Set(arr).has(obj); }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X