4980 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

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

10voto

ninjagecko Punkte 82995

Während array.indexOf(x)!=-1 ist der prägnanteste Weg, dies zu tun (und wird von Browsern, die nicht zum Internet Explorer gehören, seit über zehn Jahren unterstützt...), es ist nicht O(1), sondern eher O(N), was schrecklich ist. Wenn sich Ihr Array nicht ändert, können Sie Ihr Array in eine Hashtabelle konvertieren und dann Folgendes tun table[x]!==undefined o ===undefined :

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

Demo:

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

(Leider können Sie zwar ein Array.prototype.contains erstellen, um ein Array "einzufrieren" und eine Hashtabelle in this._cache in zwei Zeilen zu speichern, aber das würde zu falschen Ergebnissen führen, wenn Sie Ihr Array später bearbeiten wollen. JavaScript hat nicht genügend Hooks, um diesen Zustand zu erhalten, im Gegensatz zu Python zum Beispiel).

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