it-swarm.com.de

Wie überprüfe ich, ob ein Array ein Objekt in JavaScript enthält?

Wie kann ich am besten herausfinden, ob ein JavaScript-Array ein Objekt enthält?

Nur so weiß ich es zu tun:

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

Gibt es einen besseren und prägnanteren Weg, dies zu erreichen?

Dies steht in engem Zusammenhang mit der Stack Overflow-Frage Beste Methode, um ein Element in einem JavaScript-Array zu finden?, Das die Suche nach Objekten in einem Array mithilfe von indexOf anspricht.

3459
brad

Aktuelle Browser haben Array#includes , was genau that, wird weitgehend unterstützt und für ältere Browser ein polyfill hat.

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

Sie können auch Array#indexOf verwenden. Dies ist weniger direkt, erfordert jedoch keine Polyfills für veraltete Browser.

jQuery bietet $.inArray an, was funktional Array#indexOf entspricht.

underscore.js , eine JavaScript-Hilfsprogrammbibliothek, bietet _.contains(list, value) , Alias ​​_.include(list, value), die beide intern indexOf verwenden, wenn ein JavaScript-Array übergeben wird.

Einige andere Frameworks bieten ähnliche Methoden an:

Beachten Sie, dass einige Frameworks dies als Funktion implementieren, während andere sie dem Array-Prototyp hinzufügen.

3894
codeape

Update: Wie @orip in Kommentaren erwähnt, wurde der verknüpfte Benchmark 2008 durchgeführt, sodass die Ergebnisse für moderne Browser möglicherweise nicht relevant sind. Sie benötigen dies jedoch wahrscheinlich, um nicht moderne Browser zu unterstützen, und sie wurden wahrscheinlich seitdem nicht aktualisiert. Testen Sie immer selbst.

Wie andere bereits gesagt haben, ist die Iteration durch das Array wahrscheinlich der beste Weg, aber wurde bewiesen , dass eine abnehmende while-Schleife der schnellste Weg ist, um in JavaScript zu iterieren. Sie können Ihren Code also wie folgt umschreiben:

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

Natürlich können Sie auch den Array-Prototyp erweitern:

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

Und jetzt können Sie einfach Folgendes verwenden:

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

indexOfNAME _ vielleicht, aber es ist eine "JavaScript-Erweiterung des ECMA-262-Standards; als solche ist sie möglicherweise in anderen Implementierungen des Standards nicht vorhanden."

Beispiel:

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

AFAICS Microsoft bietet keine Alternative dazu, aber Sie können Arrays in Internet Explorer (und eine ähnliche Funktionalität hinzufügen andere Browser, die indexOfnicht unterstützen), wenn Sie möchten, wie eine schnelle Google-Suche zeigt (zum Beispiel diese ).

184
cic

ECMAScript 7 führt Array.prototype.includes ein.

Es kann wie folgt verwendet werden:

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

Es akzeptiert auch ein optionales zweites Argument fromIndex:

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

Im Gegensatz zu indexOf, das den Strict Equality Comparison verwendet, vergleicht includes den SameValueZero - Gleichheitsalgorithmus. Das bedeutet, dass Sie feststellen können, ob ein Array eine NaN enthält:

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

Anders als indexOf überspringt includes fehlende Indizes nicht:

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

Derzeit ist es noch ein Entwurf, es kann jedoch polyfilled sein, damit es in allen Browsern funktioniert.

140
Oriol

b ist der Wert und a ist das Array. Es gibt true oder false zurück:

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

Hier ist eine JavaScript 1.6-kompatible -Implementierung 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;
        };
}
71
Már Örlygsson

Die obersten Antworten gehen von primitiven Typen aus. Wenn Sie jedoch herausfinden möchten, ob ein Array ein Objekt mit bestimmten Eigenschaften enthält, ist Array.prototype.some () eine sehr elegante Lösung:

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

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

Das Schöne daran ist, dass die Iteration abgebrochen wird, sobald das Element gefunden wurde, sodass unnötige Iterationszyklen eingespart werden.

Außerdem passt es gut in eine if-Anweisung, da es einen Booleschen Wert zurückgibt:

if (items.some(item => item.a === '3')) {
  // do something
}

* Wie jamess in dem Kommentar darauf hinweist, wird Array.prototype.some() ab heute, September 2018, vollständig unterstützt: caniuse.com Support-Tabelle

66
Michael

Benutzen:

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

// Usage
if(isInArray(my_array, "my_value"))
{
    //...
}
50
Matías Cánepa

Das Erweitern des JavaScript-Objekts Array ist eine wirklich schlechte Idee, da Sie neue Eigenschaften (Ihre benutzerdefinierten Methoden) in for-in-Schleifen einfügen, die vorhandene Skripts brechen können. Vor einigen Jahren mussten die Autoren der Prototype - Bibliothek ihre Bibliotheksimplementierung überarbeiten, um nur solche Dinge zu entfernen.

Wenn Sie sich keine Gedanken über die Kompatibilität mit anderem JavaScript machen müssen, das auf Ihrer Seite ausgeführt wird, sollten Sie dies tun. Andernfalls würde ich die unbequemere, aber sicherere freistehende Funktionslösung empfehlen.

42
Mason Houtz

Wenn Sie für eine Sekunde aus dem Kasten heraus denken, wenn Sie diesen Anruf viele Male tätigen, ist die Verwendung wesentlich effizienter ein assoziatives Array eine Map, um Lookups mit einer Hash-Funktion durchzuführen.

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

27
MattMcKnight

Einzeiler:

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

Ich benutze folgendes:

Array.prototype.contains = function (v) {
    return this.indexOf(v) > -1;
}

var a = [ 'foo', 'bar' ];

a.contains('foo'); // true
a.contains('fox'); // false
22
Eduardo Cuomo
function contains(a, obj) {
    return a.some(function(element){return element == obj;})
}

Array.prototype.some () wurde in der 5. Ausgabe zum ECMA-262-Standard hinzugefügt

19
dansalmo

Eine hoffentlich schnellere bidirektionale indexOf/lastIndexOf alternative

2015

Während die neue Methode include sehr nett ist, ist der Support im Moment null.

Ich habe lange daran gedacht, die langsamen Funktionen indexOf/lastIndexOf zu ersetzen.

Es wurde bereits ein performanter Weg gefunden, der die wichtigsten Antworten betrachtet. Von diesen habe ich die contains-Funktion ausgewählt, die von @Damir Zekic gepostet wurde, die die schnellste sein sollte. Es heißt aber auch, dass die Benchmarks aus dem Jahr 2008 stammen und somit veraltet sind.

Ich bevorzuge auch while gegenüber for, aber aus einem bestimmten Grund beendete ich das Schreiben der Funktion mit einer for-Schleife. Es könnte auch mit einem while -- durchgeführt werden.

Ich war gespannt, ob die Iteration viel langsamer war, wenn ich währenddessen beide Seiten des Arrays überprüfe. Anscheinend nein, und daher ist diese Funktion etwa zweimal schneller als die Top-Stimmen. Natürlich ist es auch schneller als der native. In einer realen Umgebung, in der Sie nie wissen, ob der von Ihnen gesuchte Wert am Anfang oder am Ende des Arrays liegt.

Wenn Sie wissen, dass Sie gerade ein Array mit einem Wert gepusht haben, ist die Verwendung von lastIndexOf wahrscheinlich die beste Lösung. Wenn Sie jedoch große Arrays durchlaufen müssen und das Ergebnis überall vorhanden sein könnte, könnte dies eine solide Lösung sein, um die Abläufe zu beschleunigen.

Bidirektionaler IndexOf/LastIndexOf

function bidirectionalIndexOf(a, b, c, d, e){
  for(c=a.length,d=c*1; c--; ){
    if(a[c]==b) return c; //or this[c]===b
    if(a[e=d-1-c]==b) return e; //or a[e=d-1-c]===b
  }
  return -1
}

//Usage
bidirectionalIndexOf(array,'value');

Leistungstest

http://jsperf.com/bidirectionalindexof

Als Test habe ich ein Array mit 100k Einträgen erstellt.

Drei Abfragen: am Anfang, in der Mitte und am Ende des Arrays.

Ich hoffe, Sie finden das auch interessant und testen die Leistung.

Hinweis: Wie Sie sehen, habe ich die Funktion contains etwas geändert, um die Ausgabe von indexOf & lastIndexOf wiederzugeben (also im Grunde true mit index und false mit -1). Das sollte nicht schaden.

Die Array-Prototypvariante

Object.defineProperty(Array.prototype,'bidirectionalIndexOf',{value:function(b,c,d,e){
  for(c=this.length,d=c*1; c--; ){
    if(this[c]==b) return c; //or this[c]===b
    if(this[e=d-1-c] == b) return e; //or this[e=d-1-c]===b
  }
  return -1
},writable:false, enumerable:false});

// Usage
array.bidirectionalIndexOf('value');

Die Funktion kann auch leicht geändert werden, um wahr oder falsch oder sogar das Objekt, den String oder was auch immer es ist, zurückzugeben.

Und hier ist die Variable while:

function bidirectionalIndexOf(a, b, c, d){
  c=a.length; d=c-1;
  while(c--){
    if(b===a[c]) return c;
    if(b===a[d-c]) return d-c;
  }
  return c
}

// Usage
bidirectionalIndexOf(array,'value');

Wie ist das möglich?

Ich denke, dass die einfache Berechnung, um den reflektierten Index in einem Array zu erhalten, so einfach ist, dass sie zweimal schneller ist als eine tatsächliche Schleifeniteration.

Hier ist ein komplexes Beispiel, das drei Prüfungen pro Iteration durchführt. Dies ist jedoch nur bei einer längeren Berechnung möglich, die zu einer Verlangsamung des Codes führt.

http://jsperf.com/bidirectionalindexof/2

14
cocco

Wenn Sie wiederholt prüfen, ob ein Objekt in einem Array vorhanden ist, sollten Sie dies vielleicht überprüfen

  1. Halten Sie das Array immer sortiert, indem Sie insert sort in Ihrem Array ausführen (neue Objekte an der richtigen Stelle einfügen). 
  2. Aktualisieren Sie Objekte wie Entfernen + Sortierte Einfügeoperation und
  3. Verwenden Sie eine binäre Suche Suche in Ihrer contains(a, obj).
12
Ztyx

Wir verwenden dieses Snippet (arbeitet mit Objekten, Arrays, Strings):

/*
 * @function
 * @name Object.prototype.inArray
 * @description Extend Object prototype within inArray function
 *
 * @param {mix}    needle       - Search-able needle
 * @param {bool}   searchInKey  - Search needle in keys?
 *
 */
Object.defineProperty(Object.prototype, 'inArray',{
    value: function(needle, searchInKey){

        var object = this;

        if( Object.prototype.toString.call(needle) === '[object Object]' || 
            Object.prototype.toString.call(needle) === '[object Array]'){
            needle = JSON.stringify(needle);
        }

        return Object.keys(object).some(function(key){

            var value = object[key];

            if( Object.prototype.toString.call(value) === '[object Object]' || 
                Object.prototype.toString.call(value) === '[object Array]'){
                value = JSON.stringify(value);
            }

            if(searchInKey){
                if(value === needle || key === needle){
                return true;
                }
            }else{
                if(value === needle){
                    return true;
                }
            }
        });
    },
    writable: true,
    configurable: true,
    enumerable: false
});

Verwendungszweck:

var a = {one: "first", two: "second", foo: {three: "third"}};
a.inArray("first");          //true
a.inArray("foo");            //false
a.inArray("foo", true);      //true - search by keys
a.inArray({three: "third"}); //true

var b = ["one", "two", "three", "four", {foo: 'val'}];
b.inArray("one");         //true
b.inArray('foo');         //false
b.inArray({foo: 'val'})   //true
b.inArray("{foo: 'val'}") //false

var c = "String";
c.inArray("S");        //true
c.inArray("s");        //false
c.inArray("2", true);  //true
c.inArray("20", true); //false
12
dr.dimitru
function inArray(elem,array)
{
    var len = array.length;
    for(var i = 0 ; i < len;i++)
    {
        if(array[i] == elem){return i;}
    }
    return -1;
} 

Gibt den Array-Index zurück, wenn er gefunden wird, oder -1, falls nicht gefunden

12
LmC

Wenn Sie JavaScript 1.6 oder höher (Firefox 1.5 oder höher) verwenden, können Sie Array.indexOf verwenden. Ansonsten glaube ich, dass Sie am Ende etwas Ähnliches wie Ihren ursprünglichen Code erhalten.

10
Andru Luvisi

Verwenden Sie lodash's einige Funktion.

Es ist prägnant, präzise und bietet eine hervorragende Plattformunterstützung.

Die akzeptierte Antwort erfüllt nicht einmal die Anforderungen.

Anforderungen: Empfiehlt eine präzise und effiziente Methode, 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 zu bestimmen, ob ein scalar -Wert in einem Array von Skalaren vorhanden ist ...

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

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

Um sowohl Skalare als auch Objekte zu behandeln, können Sie Folgendes tun:

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

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

Verwendungszweck:

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

Verwendungszweck:

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

Warum JSON.stringify verwenden?

Array.indexOf und Array.includes (sowie die meisten Antworten hier) werden nur nach Verweis und nicht nach Wert verglichen.

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

Bonus

Nicht optimierter ES6-Einliner:

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

Hinweis: Das Vergleichen von Objekten nach Wert funktioniert besser, wenn sich die Schlüssel in derselben Reihenfolge befinden. Um sicher zu sein, können Sie die Schlüssel zuerst mit einem Paket wie diesem sortieren: https://www.npmjs.com/ Paket/Sortierschlüssel


contains-Funktion wurde mit einer Perf-Optimierung aktualisiert. Danke itinance für den Hinweis.

9
Igor Barbashin

array.indexOf(x)!=-1 ist zwar die präziseste Methode (und wird seit über zehn Jahren von Nicht-Internet Explorer-Browsern unterstützt ...), aber nicht O (1), sondern O (N), was schrecklich ist. Wenn sich Ihr Array nicht ändert, können Sie Ihr Array in eine Hashtabelle konvertieren. Führen Sie dann table[x]!==undefined oder ===undefined aus:

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

(Sie können zwar ein Array.prototype.contains erstellen, um ein Array "einzufrieren" und eine Hashtable in this._cache in zwei Zeilen zu speichern, was jedoch zu falschen Ergebnissen führt, wenn Sie das Array später bearbeiten.) JavaScript verfügt nicht über ausreichende Hooks Lassen Sie diesen Status im Gegensatz zu Python zum Beispiel bei.)

8
ninjagecko

ECMAScript 6 hat einen eleganten Vorschlag zum Finden.

Die find-Methode führt die Callback-Funktion einmal für jedes Element aus im Array vorhanden, bis ein Array gefunden wird, in dem Callback ein wahres _ zurückgibt. Wert. Wenn ein solches Element gefunden wird, gibt find sofort den Wert .__ zurück. dieses Elements. Andernfalls suchen Sie die Rückgaben undefiniert. Rückruf ist wird nur für Indizes des Arrays aufgerufen, denen Werte zugewiesen wurden; es wird nicht für Indizes aufgerufen, die gelöscht wurden oder die niemals wurden Werte zugewiesen.

Hier ist die MDN-Dokumentation dazu.

Die Suchfunktion funktioniert so.

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 die Funktion definieren.

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

Benutzen:

var myArray = ['yellow', 'orange', 'red'] ;

alert(!!~myArray.indexOf('red')); //true

Demo

Um genau zu wissen, was die tilde~ an dieser Stelle tut, lesen Sie diese Frage Was macht eine Tilde, wenn sie vor einem Ausdruck steht?.

6
Mina Gabriel

So macht Prototype es :

/**
 *  Array#indexOf(item[, offset = 0]) -> Number
 *  - item (?): A value that may or may not be in the array.
 *  - offset (Number): The number of initial items to skip before beginning the
 *      search.
 *
 *  Returns the position of the first occurrence of `item` within the array &mdash; or
 *  `-1` if `item` doesn't exist in the array.
**/
function indexOf(item, i) {
  i || (i = 0);
  var length = this.length;
  if (i < 0) i = length + i;
  for (; i < length; i++)
    if (this[i] === item) return i;
  return -1;
}

Siehe auch hier wie sie es anschließen.

4
Ken

Sie können diesen Trick auch verwenden:

var arrayContains = function(object) {
  return (serverList.filter(function(currentObject) {
    if (currentObject === object) {
      return currentObject
    }
    else {
      return false;
    }
  }).length > 0) ? true : false
}
3
user2724028

OK, du kannst einfach optimiere deinen Code um das Ergebnis zu erhalten! 

Es gibt viele Möglichkeiten, dies zu tun, die sauberer und besser sind, aber ich wollte nur Ihr Muster bekommen und es mit JSON.stringify anwenden.

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

Benutzen:

Array.prototype.contains = function(x){
  var retVal = -1;

  // x is a primitive type
  if(["string","number"].indexOf(typeof x)>=0 ){ retVal = this.indexOf(x);}

  // x is a function
  else if(typeof x =="function") for(var ix in this){
    if((this[ix]+"")==(x+"")) retVal = ix;
  }

  //x is an object...
  else {
    var sx=JSON.stringify(x);
    for(var ix in this){
      if(typeof this[ix] =="object" && JSON.stringify(this[ix])==sx) retVal = ix;
    }
  }

  //Return False if -1 else number if numeric otherwise string
  return (retVal === -1)?false : ( isNaN(+retVal) ? retVal : +retVal);
}

Ich weiß, dass dies nicht der beste Weg ist, aber da es keine native IComparable Möglichkeit gibt, zwischen Objekten zu interagieren, denke ich, dass dies so nahe ist, wie Sie zwei Entitäten in einem Array vergleichen können. Das Erweitern des Array-Objekts ist möglicherweise nicht sinnvoll, aber manchmal ist es in Ordnung (wenn Sie sich dessen und dem Kompromiss bewusst sind).

3
Carlos A

Man kann Set verwenden, das 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'));
3
rlib
  1. Verwenden Sie entweder Array.indexOf(Object)
  2. Mit ECMA 7 kann die Array.includes(Object) verwendet werden. 
  3. Mit ECMA 6 können Sie Array.find(FunctionName) verwenden, wobei FunctionName eine vom Benutzer definierte Funktion ist.

    Hoffe das hilft!

2
kg11

Wie bereits erwähnt, können Sie Array.indexOf verwenden, es ist jedoch nicht in allen Browsern verfügbar. Hier ist der Code aus https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf , damit er in älteren Browsern gleich funktioniert.

indexOf ist eine kürzlich erfolgte Erweiterung des ECMA-262-Standards. als solche kann es nicht in allen Browsern vorhanden sein. Sie können dies umgehen, indem Sie .__ einfügen. Der folgende Code am Anfang Ihrer Skripte erlaubt die Verwendung von indexOf in Implementierungen, die es nicht nativ unterstützen. Diese Der Algorithmus ist genau der in ECMA-262, 5. Auflage, .__ angegebene. Angenommen, Object, TypeError, Number, Math.floor, Math.abs und Math.max haben ihren ursprünglichen Wert.

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

Überrascht, dass zu dieser Frage immer noch keine neue Syntax hinzugefügt wurde, die meine 2 Cent hinzufügt.

Nehmen wir an, wir haben ein Array von Objekten arrObj und möchten obj darin suchen.

Array.prototype.indexOf -> (gibt index oder -1 zurück) wird im Allgemeinen verwendet, um den Index eines Elements im Array zu finden. Dies kann auch zum Suchen von Objekten verwendet werden, funktioniert jedoch nur, wenn Sie einen Verweis auf dasselbe Objekt übergeben.

let obj = { name: 'Sumer', age: 36 };
let arrObj = [obj, { name: 'Kishor', age: 46 }, { name: 'Rupen', age: 26 }];


console.log(arrObj.indexOf(obj));// 0
console.log(arrObj.indexOf({ name: 'Sumer', age: 36 })); //-1

console.log([1, 3, 5, 2].indexOf(2)); //3

Array.prototype. includes -> (gibt true oder false zurück)

console.log(arrObj.includes(obj));  //true
console.log(arrObj.includes({ name: 'Sumer', age: 36 })); //false

console.log([1, 3, 5, 2].includes(2)); //true

Array.prototype. find -> (nimmt einen Rückruf entgegen, gibt zuerst value/object zurück, das in CB true zurückgibt).

console.log(arrObj.find(e => e.age > 40));  //{ name: 'Kishor', age: 46 }
console.log(arrObj.find(e => e.age > 40)); //{ name: 'Kishor', age: 46 }

console.log([1, 3, 5, 2].find(e => e > 2)); //3

Array.prototype. findIndex -> (nimmt einen Rückruf entgegen, gibt index des ersten Werts/Objekts zurück, der in CB true zurückgibt).

console.log(arrObj.findIndex(e => e.age > 40));  //1
console.log(arrObj.findIndex(e => e.age > 40)); //1

console.log([1, 3, 5, 2].findIndex(e => e > 2)); //1

Da find und findIndex einen Rückruf annehmen, können wir jedes Objekt (auch wenn wir nicht über die Referenz verfügen) aus dem Array abrufen, indem wir die wahre Bedingung kreativ festlegen.

2
Sumer

Auf keinen Fall das Beste, aber ich wurde gerade kreativ und fügte das Repertoire hinzu.

Verwenden Sie dies nicht

Object.defineProperty(Array.prototype, 'exists', {
  value: function(element, index) {

    var index = index || 0

    return index === this.length ? -1 : this[index] === element ? index : this.exists(element, ++index)
  }
})


// Outputs 1
console.log(['one', 'two'].exists('two'));

// Outputs -1
console.log(['one', 'two'].exists('three'));

console.log(['one', 'two', 'three', 'four'].exists('four'));

2
sqram

Ich habe die eingereichten Antworten durchgesehen und erfuhr, dass sie nur zutreffen, wenn Sie das Objekt per Referenz suchen. Eine einfache lineare Suche mit Referenzobjektvergleich. 

Aber nehmen wir an, Sie haben keinen Verweis auf ein Objekt. Wie finden Sie das richtige Objekt im Array? Sie müssen mit jedem Objekt einen linearen und tiefen Vergleich durchführen. Stellen Sie sich vor, wenn die Liste zu groß ist und die darin enthaltenen Objekte sehr groß sind und große Textteile enthalten. Die Leistung sinkt drastisch mit der Anzahl und Größe der Elemente im Array.

Sie können Objekte stringifizieren und in die systemeigene Hashtabelle einfügen, dann haben Sie jedoch Datenredundanz, die diese Schlüssel in Erinnerung bringt, da JavaScript sie für 'for i in obj' hält, und Sie möchten nur prüfen, ob das Objekt vorhanden ist oder nicht Du hast den Schlüssel.

Ich habe darüber nachgedacht, einen JSON-Schema-Validator zu erstellen, und habe einen einfachen Wrapper für die native Hash-Tabelle entwickelt, der der einzigen Hash-Implementierung ähnlich ist, mit einigen Optimierungsausnahmen, die ich der native Hash-Tabelle überlassen musste. Es ist nur ein Leistungs-Benchmarking erforderlich ....__ Alle Details und Code finden Sie in meinem Blog: http://stamat.wordpress.com/javascript-quickly-find-very-large-objects-in-a -large-array/ Ich werde in Kürze Benchmark-Ergebnisse veröffentlichen. 

Die Komplettlösung funktioniert so:

var a = {'a':1,
 'b':{'c':[1,2,[3,45],4,5],
 'd':{'q':1, 'b':{'q':1, 'b':8},'c':4},
 'u':'lol'},
 'e':2};

 var b = {'a':1, 
 'b':{'c':[2,3,[1]],
 'd':{'q':3,'b':{'b':3}}},
 'e':2};

 var c = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.";

 var hc = new HashCache([{a:3, b:2, c:5}, {a:15, b:2, c:'foo'}]); //init

 hc.put({a:1, b:1});
 hc.put({b:1, a:1});
 hc.put(true);
 hc.put('true');
 hc.put(a);
 hc.put(c);
 hc.put(d);
 console.log(hc.exists('true'));
 console.log(hc.exists(a));
 console.log(hc.exists(c));
 console.log(hc.exists({b:1, a:1}));
 hc.remove(a);
 console.log(hc.exists(c));
1
stamat

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 performanter sein als bei jeder anderen Methode

1
Neil Girardi

Oder diese Lösung:

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

Ähnliches: Findet das erste Element durch ein "Suchlambda":

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

Verwendungszweck:

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

Gleiches in Kaffeescript:

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

Ich habe an einem Projekt gearbeitet, bei dem ich eine Funktionalität wie Python set benötigte, die alle Duplikate entfernt und eine neue Liste zurückgibt. Ich habe diese Funktion also für jemanden nützlich geschrieben

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

Ich empfahl, die Unterstreichungsbibliothek zu verwenden, da sie den Wert zurückgibt und für alle Browser unterstützt wird. 

unterstriche

 var findValue = _.find(array, function(item) {
    return item.id == obj.id;
 });
1
Durgpal Singh

Es hat einen Parameter: eine Array-Anzahl von Objekten. Jedes Objekt im Array verfügt über zwei ganzzahlige Eigenschaften, die mit x und y bezeichnet werden. Die Funktion muss eine Anzahl aller Objekte im Array zurückgeben, die numbers.x == numbers.y entsprechen.

var numbers = [ { x: 1, y: 1 },
                 { x: 2, y: 3 },
                 { x: 3, y: 3 },
                 { x: 3, y: 4 },
                 { x: 4, y: 5 } ];
    count = 0; 
var n = numbers.length;
for (var i =0;i<n;i++)
{
  if(numbers[i].x==numbers[i].y)
  {count+=1;}
}

alert(count);
1
Mitul Panchal

Mit idnexOf () ist es eine gute Lösung, aber Sie sollten die eingebettete Implementierungsfunktion indexOf () ausblenden, die -1 mit dem Operator ~ zurückgibt: 

function include(arr,obj) { 
    return !!(~arr.indexOf(obj)); 
} 
0
KRRySS

Zusätzlich zu dem, was andere sagten, wenn Sie keinen Verweis auf das Objekt haben, das Sie im Array suchen möchten, können Sie so etwas tun.

let array = [1, 2, 3, 4, {"key": "value"}];

array.some((element) => JSON.stringify(element) === JSON.stringify({"key": "value"})) // true

array.some((element) => JSON.stringify(element) === JSON.stringify({})) // true

Array.some gibt true zurück, wenn ein Element der angegebenen Bedingung entspricht, und gibt false zurück, wenn keines der Elemente der angegebenen Bedingung entspricht.

0
Nitesh Ranjan

Verwenden Sie JavaScript-In-Build-Funktion

var optval = [];

optval.Push('A');    
optval.Push('B');    
optval.Push('C');

Wir können den String A im Javascript-Array wie folgt durchsuchen:

optval.includes('A') // =====> return true
0
Rajeev Ranjan

Einfache Lösung: ES6 Features " include " Methode

let arr = [1, 2, 3, 2, 3, 2, 3, 4];

  arr.includes(2) // true

  arr.includes(93) // false
0
ngCourse
function countArray(originalArray) {

    var compressed = [];
    // make a copy of the input array
    var copyArray = originalArray.slice(0);

    // first loop goes over every element
    for (var i = 0; i < originalArray.length; i++) {

        var count = 0;  
        // loop over every element in the copy and see if it's the same
        for (var w = 0; w < copyArray.length; w++) {
            if (originalArray[i] == copyArray[w]) {
                // increase amount of times duplicate is found
                count++;
                // sets item to undefined
                delete copyArray[w];
            }
        }

        if (count > 0) {
            var a = new Object();
            a.value = originalArray[i];
            a.count = count;
            compressed.Push(a);
        }
    }

    return compressed;
};

// It should go something like this:

var testArray = new Array("dog", "dog", "cat", "buffalo", "wolf", "cat", "tiger", "cat");
var newArray = countArray(testArray);
console.log(newArray);
0
Sanjay Magar