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.

3voto

Neil Girardi Punkte 3836

Wenn Sie mit ES6 arbeiten, können Sie ein Set verwenden:

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

Dies sollte leistungsfähiger sein als jede andere Methode

4 Stimmen

Inwiefern ist sie leistungsfähiger? Zumindest müssen Sie die Menge konstruieren, die O(n) (Sie müssen über das Array iterieren). Einfach eine lineare Suche durchführen (wie indexOf tut) ist auch O(n) aber nur im schlimmsten Fall. Die durchschnittliche Komplexität liegt eher bei n/2 Denn wenn das Array das Element enthält, werden Sie wahrscheinlich irgendwo in der Mitte aufhören. Daher ist diese Methode im Durchschnitt langsamer als Array#includes y Array#indexOf .

3voto

Jeeva Punkte 1621

Ich arbeitete an einem Projekt, dass ich eine Funktionalität wie Python benötigt set die alle doppelten Werte entfernt und eine neue Liste zurückgibt, also habe ich diese Funktion geschrieben, die vielleicht für jemanden nützlich ist

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

3voto

Maxime Helen Punkte 1305

Oder diese Lösung:

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

3voto

Simon_Weaver Punkte 129442

Wie andere bereits erwähnt haben, können Sie Array.indexOf aber sie ist nicht in allen Browsern verfügbar. Hier ist der Code von https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf damit es auch in älteren Browsern funktioniert.

indexOf ist ein neuer Zusatz zum ECMA-262-Standard; daher ist er möglicherweise nicht in allen Browsern vorhanden sein. Sie können dieses Problem umgehen, indem Sie folgenden Code am Anfang Ihrer Skripte einfügen, der die Verwendung von indexOf in Implementierungen, die es nicht von Haus aus unterstützen. Dieser Algorithmus ist genau derjenige, der in ECMA-262, 5th edition, angegeben ist, unter der Annahme, dass Object, TypeError, Number, Math.floor, Math.abs, und Math.max ihren ursprünglichen Wert haben.

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

2voto

Andy Rohr Punkte 61

Ähnliches: Findet das erste Element durch ein "Such-Lambda":

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

Verwendung:

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

Dasselbe in coffeescript:

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

0 Stimmen

Dies ist sicherlich viel flexibler als viele der anderen Ansätze. Wenn man sich mit dem Prototyp nicht wohl fühlt, könnte man etwas wie var positionIf = function (predicate,sequence) {return sequence.map(predicate).indexOf(true);} in Betracht ziehen;

4 Stimmen

Ein effizienterer Weg, diese Methode zu implementieren, wäre die Verwendung einer Schleife und die Beendigung der Anwendung search_lambda sobald etwas gefunden wird.

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