1407 Stimmen

Bestimmen, ob ein Array einen Wert enthält

Ich muss feststellen, ob ein Wert in einem Array vorhanden ist.

Ich verwende die folgende Funktion:

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

Die obige Funktion gibt immer false zurück.

Die Array-Werte und der Funktionsaufruf lauten wie folgt:

arrValues = ["Sam","Great", "Sample", "High"]
alert(arrValues.contains("Sam"));

10 Stimmen

Der Code funktioniert in Safari 4.0.2. Übrigens: Ich würde eine === Vergleich anstelle von nur == .

1 Stimmen

"Die obige Funktion gibt immer false zurück." Nein, das tut sie nicht: Die Funktion funktioniert wie erwartet - der Fehler muss woanders liegen.

2 Stimmen

54voto

Nicolas Punkte 719

Seit ECMAScript6 kann man mit Set :

var myArray = ['A', 'B', 'C'];
var mySet = new Set(myArray);
var hasB = mySet.has('B'); // true
var hasZ = mySet.has('Z'); // false

0 Stimmen

Schöne Art und Weise zu verwenden, tatsächlich eingestellt.

47voto

Trevor Punkte 12546

tl;dr

function includes(k) {
  for(var i=0; i < this.length; i++){
    if( this[i] === k || ( this[i] !== this[i] && k !== k ) ){
      return true;
    }
  }
  return false;
}

Beispiel

function includes(k) {
  for(var i=0; i < this.length; i++){
    if( this[i] === k || ( this[i] !== this[i] && k !== k ) ){
      return true;
    }
  }
  return false;
}

function log(msg){
  $('#out').append('<div>' + msg + '</div>');  
}

var arr = [1, "2", NaN, true];
arr.includes = includes;

log('var arr = [1, "2", NaN, true];');
log('<br/>');
log('arr.includes(1): ' + arr.includes(1));
log('arr.includes(2): ' + arr.includes(2));
log('arr.includes("2"): ' + arr.includes("2"));
log('arr.includes(NaN): ' + arr.includes(NaN));
log('arr.includes(true): ' + arr.includes(true));
log('arr.includes(false): ' + arr.includes(false));

#out{
  font-family:monospace;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id=out></div>

Längere Antwort

Ich weiß, dass es bei dieser Frage nicht wirklich darum geht, ob eingebaute Objekte erweitert werden sollen oder nicht, aber der Versuch des OP und die Kommentare zu dieser Antwort unterstreichen diese Debatte. Mein Kommentar vom 12. Februar '13 zitiert einen Artikel, der diese Debatte sehr gut umreißt, allerdings ist der Link kaputt und ich kann den ursprünglichen Kommentar nicht bearbeiten, weil zu viel Zeit vergangen ist, daher füge ich ihn ein aquí .

Wenn Sie die eingebauten Funktionen erweitern möchten Array Objekt mit einer contains Methode ist es wahrscheinlich am besten und am verantwortungsvollsten, dieses Polyfill von MDN . (Siehe auch este Abschnitt des MDN-Artikels über prototypische Vererbung, der erklärt, dass "Der einzige gute Grund für die Erweiterung eines eingebauten Prototyps ist die Rückportierung von Funktionen neuerer JavaScript-Engines, z. B. Array.forEach usw." )

if (!Array.prototype.includes) {
  Array.prototype.includes = function(searchElement /*, fromIndex*/ ) {
    'use strict';
    var O = Object(this);
    var len = parseInt(O.length) || 0;
    if (len === 0) {
      return false;
    }
    var n = parseInt(arguments[1]) || 0;
    var k;
    if (n >= 0) {
      k = n;
    } else {
      k = len + n;
      if (k < 0) {k = 0;}
    }
    var currentElement;
    while (k < len) {
      currentElement = O[k];
      if (searchElement === currentElement ||
         (searchElement !== searchElement && currentElement !== currentElement)) {
        return true;
      }
      k++;
    }
    return false;
  };
}

Sie wollen keine strikte Gleichberechtigung, oder Sie wollen wählen?

function includes(k, strict) {
  strict = strict !== false; // default is true
  // strict = !!strict; // default is false
  for(var i=0; i < this.length; i++){
    if( (this[i] === k && strict) || 
        (this[i] == k && !strict) ||
        (this[i] !== this[i] && k !== k)
    ) {
      return true;
    }
  }
  return false;
}

4 Stimmen

Ist diese Technik der Erweiterung von eingebauten Typen nicht verpönt?

3 Stimmen

Buggy: [1,2,4].contains([].contains) wahr ist. Auch unnötig langsam durch den gleichen Fehler. Vermeiden Sie for..in über Arrays.

0 Stimmen

@Eamon Nerbonne: Ich habe diesen Code gerade in jsfiddle.net eingefügt und erhalte false. Mache ich etwas falsch. Könnten Sie außerdem erläutern, wie dieser Fehler den Code verlangsamt? Schließlich war mir nicht bewusst, dass es einen Leistungsunterschied für "for..in"-Schleifen gibt. Könnten Sie das erklären oder mich auf einen Artikel verweisen, in dem ich mehr darüber lesen kann?

22voto

Matías Cánepa Punkte 5394

Mein kleiner Beitrag:

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

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

20voto

SoEzPz Punkte 13250

Wenn Sie Zugang zu ECMA 5 haben, können Sie die einige Methode.

MDN SOME Methode Link

arrValues = ["Sam","Great", "Sample", "High"];

function namePresent(name){
  return name === this.toString();
}
// Note:
// namePresent requires .toString() method to coerce primitive value
// i.e. String {0: "S", 1: "a", 2: "m", length: 3, [[PrimitiveValue]]: "Sam"}
// into
// "Sam"

arrValues.some(namePresent, 'Sam');
=> true;

Wenn Sie Zugang zu ECMA 6 haben, können Sie die enthält Methode.

MDN INCLUDES Methode Link

arrValues = ["Sam","Great", "Sample", "High"];

arrValues.includes('Sam');
=> true;

18voto

rlovtang Punkte 4790

Angesichts der Implementierung von indexOf für IE (wie von eyelidlessness beschrieben):

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

9 Stimmen

Das ist überflüssig.

10 Stimmen

Vielleicht, aber es macht Ihren Code sauberer. if (myArray.contains(obj)) ist einfacher zu lesen und erklärt die Absicht besser als if (myArray.indexOf(obj) > -1). Ich würde auf jeden Fall beides implementieren.

0 Stimmen

Funktioniert dies in allen Browsern? Oder betrachten einige Browser den Index von "2" und 2 als dasselbe?

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