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.

126voto

william malo Punkte 2420

Nehmen wir an, Sie haben ein Array wie folgt definiert:

const array = [1, 2, 3, 4]

Nachstehend finden Sie drei Möglichkeiten, um zu prüfen, ob ein 3 da drin. Alle von ihnen geben entweder true o false .

Native Array-Methode (seit ES2016) ( Kompatibilitätstabelle )

array.includes(3) // true

Als benutzerdefinierte Array-Methode (vor ES2016)

// Prefixing the method with '_' to avoid name clashes
Object.defineProperty(Array.prototype, '_includes', { value: function (v) { return this.indexOf(v) !== -1 }})
array._includes(3) // true

Einfache Funktion

const includes = (a, v) => a.indexOf(v) !== -1
includes(array, 3) // true

64 Stimmen

"~" ist ein Operator, der 1 von einer Zahl abzieht. indexOf gibt -1 zurück, wenn es fehlschlägt, also macht ~" aus -1 eine 0. Mit "!!" werden Zahlen zu Boleans (!!0===false)

87voto

Már Örlygsson Punkte 13768

Hier ist ein Kompatibel mit JavaScript 1.6 Umsetzung von 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;
        };
}

0 Stimmen

Das sieht toll aus, aber ich bin etwas verwirrt: * Sind die Tests in den Zeilen 1 und 3 nicht gleichwertig? * Wäre es nicht besser, den Prototyp zu testen und die Funktion bei Bedarf zu Array.prototype hinzuzufügen?

12 Stimmen

Sie sind nicht gleichwertig. [].indexOf ist eine Abkürzung für Array.prototype.indexOf . Wir paranoid-defensiven Javascript-Programmierer vermeiden die Erweiterung nativer Prototypen um jeden Preis.

2 Stimmen

Ist nicht [].indexOf Erstellung eines neuen Arrays und anschließender Zugriff auf indexOf , während Array.prototype.indexOf einfach direkt auf den Prototyp zugreift?

62voto

Matías Cánepa Punkte 5394

Verwendung:

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

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

27 Stimmen

x ? true : false ist in der Regel überflüssig. Es ist hier.

1 Stimmen

@minitech Warum sagen Sie, es sei überflüssig?

11 Stimmen

array.indexOf(search) >= 0 ist bereits ein Boolescher Wert. Einfach return array.indexOf(search) >= 0 .

58voto

Erweitern des JavaScript Array Objekts ist eine wirklich schlechte Idee, denn Sie führen neue Eigenschaften (Ihre eigenen Methoden) in for-in Schleifen, die bestehende Skripte unterbrechen können. Vor ein paar Jahren haben die Autoren des Prototyp Bibliothek musste ihre Bibliotheksimplementierung überarbeiten, um genau diese Art von Dingen zu entfernen.

Wenn Sie sich keine Gedanken über die Kompatibilität mit anderen JavaScript-Funktionen auf Ihrer Seite machen müssen, sollten Sie dies tun.

25 Stimmen

Ich bin anderer Meinung. For-in-Schleifen sollten nicht für Arrays aus genau diesem Grund verwendet werden. Mit for-in-Schleifen wird brechen, wenn eine der beliebten js-Bibliotheken verwenden

46voto

Kamil Kiełczewski Punkte 69048

Leistung

Heute 2020.01.07 führe ich Tests auf MacOs HighSierra 10.13.6 mit Chrome v78.0.0, Safari v13.0.4 und Firefox v71.0.0 für 15 ausgewählte Lösungen durch. Schlussfolgerungen

  • Lösungen basierend auf JSON , Set und überraschenderweise find (K,N,O) sind bei allen Browsern am langsamsten
  • der es6 includes (F) ist nur auf Chrom schnell
  • die Lösungen auf der Grundlage for (C,D) und indexOf (G,H) sind auf allen Browsern auf kleinen und großen Arrays recht schnell, so dass sie wahrscheinlich die beste Wahl für eine effiziente Lösung sind
  • die Lösungen, bei denen der Index während der Schleife abnimmt, (B) ist langsamer, wahrscheinlich weil die Art der CPU-Cache funktioniert .
  • Ich habe auch einen Test für ein großes Array durchgeführt, bei dem das gesuchte Element an der Position 66% der Array-Länge war, und die Lösungen basieren auf for (C,D,E) ergibt ähnliche Ergebnisse (~630 ops/sec - aber E war auf Safari und Firefox 10-20% langsamer als C und D)

Ergebnisse

enter image description here

Einzelheiten

Ich führe 2 Testfälle durch: für ein Array mit 10 Elementen und ein Array mit 1 Million Elementen. In beiden Fällen setzen wir das gesuchte Element in die Mitte des Arrays.

let log = (name,f) => console.log(`${name}: 3-${f(arr,'s10')}  's7'-${f(arr,'s7')}  6-${f(arr,6)} 's3'-${f(arr,'s3')}`)

let arr = [1,2,3,4,5,'s6','s7','s8','s9','s10'];
//arr = new Array(1000000).fill(123); arr[500000]=7;

function A(a, val) {
    var i = -1;
    var n = a.length;
    while (i++<n) {
       if (a[i] === val) {
           return true;
       }
    }
    return false;
}

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

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

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

function E(a, val){  
  var n = a.length-1;
  var t = n/2;
  for (var i = 0; i <= t; i++) {
        if (a[i] === val || a[n-i] === val) return true;
  }
  return false;
}

function F(a,val) {
    return a.includes(val);
}

function G(a,val) {
    return a.indexOf(val)>=0;
}

function H(a,val) {
    return !!~a.indexOf(val);
}

function I(a, val) {
  return a.findIndex(x=> x==val)>=0;
}

function J(a,val) {
    return a.some(x=> x===val);
}

function K(a, val) {
  const s = JSON.stringify(val);
  return a.some(x => JSON.stringify(x) === s);
}

function L(a,val) {
    return !a.every(x=> x!==val);
}

function M(a, val) {
  return !!a.find(x=> x==val);
}

function N(a,val) {
    return a.filter(x=>x===val).length > 0;
}

function O(a, val) {
  return new Set(a).has(val);
}

log('A',A);
log('B',B);
log('C',C);
log('D',D);
log('E',E);
log('F',F);
log('G',G);
log('H',H);
log('I',I);
log('J',J);
log('K',K);
log('L',L);
log('M',M);
log('N',N);
log('O',O);

This shippet only presents functions used in performance tests - it not perform tests itself!

Array klein - 10 Elemente

Sie können Tests in Ihrer Maschine durchführen HIER

enter image description here

Array groß - 1.000.000 Elemente

Sie können Tests in Ihrer Maschine durchführen HIER

enter image description here

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