477 Stimmen

Wie findet man das erste Element eines Arrays, das einer booleschen Bedingung in JavaScript entspricht?

Ich frage mich, ob es eine bekannte, integrierte/elegante Weise, das erste Element eines JS-Arrays zu finden, die eine bestimmte Bedingung übereinstimmt. Ein C#-Äquivalent würde sein Liste.Finden .

Bisher habe ich eine solche Zweifunktionskombination verwendet:

// Returns the first element of an array that satisfies given predicate
Array.prototype.findFirst = function (predicateCallback) {
    if (typeof predicateCallback !== 'function') {
        return undefined;
    }

    for (var i = 0; i < arr.length; i++) {
        if (i in this && predicateCallback(this[i])) return this[i];
    }

    return undefined;
};

// Check if element is not undefined && not null
isNotNullNorUndefined = function (o) {
    return (typeof (o) !== 'undefined' && o !== null);
};

Und dann kann ich sie benutzen:

var result = someArray.findFirst(isNotNullNorUndefined);

Da es aber auch so viele funktionale Array-Methoden in ECMAScript Vielleicht gibt es ja schon so etwas? Ich kann mir vorstellen, dass viele Leute so etwas ständig implementieren müssen...

566voto

Bergi Punkte 565633

Seit ES6 gibt es die native find méthode für Arrays; dies stoppt die Aufzählung des Arrays, sobald es die erste Übereinstimmung findet, und gibt den Wert zurück.

const result = someArray.find(isNotNullNorUndefined);

Alte Antwort:

Ich muss eine Antwort schreiben, um diese zu stoppen filter Vorschläge :-)

da es so viele funktionale Array-Methoden in ECMAScript gibt, gibt es vielleicht schon so etwas?

Sie können die some Array-Methode um das Array zu iterieren, bis eine Bedingung erfüllt ist (und dann anzuhalten). Leider wird nur zurückgegeben, ob die Bedingung einmal erfüllt wurde, nicht aber durch welches Element (oder bei welchem Index) sie erfüllt wurde. Also müssen wir es ein wenig abändern:

function find(arr, test, ctx) {
    var result = null;
    arr.some(function(el, i) {
        return test.call(ctx, el, i, arr) ? ((result = el), true) : false;
    });
    return result;
}

var result = find(someArray, isNotNullNorUndefined);

143voto

Mark Amery Punkte 124946

Ab ECMAScript 6 können Sie mit Array.prototype.find für diese. Dies ist implementiert und funktioniert in Firefox (25.0), Chrome (45.0), Edge (12) und Safari (7.1), aber nicht im Internet Explorer oder auf einer Reihe anderer alter oder ungewöhnlicher Plattformen .

Zum Beispiel, x unten ist 106 :

const x = [100,101,102,103,104,105,106,107,108,109].find(function (el) {
    return el > 105;
});
console.log(x);

Wenn Sie dies sofort verwenden möchten, aber Unterstützung für IE oder andere nicht unterstützende Browser benötigen, können Sie ein Shim verwenden. Ich empfehle die es6-shim . MDN bietet auch eine Unterlegscheibe wenn Sie aus irgendeinem Grund nicht das gesamte es6-Shim in Ihr Projekt einbauen wollen. Um maximale Kompatibilität zu erreichen, sollten Sie das es6-shim verwenden, da es im Gegensatz zur MDN-Version fehlerhafte native Implementierungen von find und überschreibt sie (siehe den Kommentar, der mit "Fehler in Array#find und Array#findIndex beheben" und die unmittelbar darauf folgenden Zeilen).

86voto

Phil Mander Punkte 1699

Wie wäre es mit der Verwendung von Filter und den ersten Index aus dem resultierenden Array erhalten?

var result = someArray.filter(isNotNullNorUndefined)[0];

83voto

Willem van der Veen Punkte 26043

Zusammenfassung:

  • Um das erste Element in einem Array zu finden, das einer booleschen Bedingung entspricht, können wir die ES6 find()
  • find() befindet sich auf Array.prototype so dass es für jedes Array verwendet werden kann.
  • find() nimmt einen Rückruf entgegen, bei dem ein boolean Bedingung getestet wird. Die Funktion gibt die Wert (nicht der Index!)

Exemple :

const array = [4, 33, 8, 56, 23];

const found = array.find(element => {
  return element > 50;
});

console.log(found);   //  56

17voto

Ja͢ck Punkte 165747

Es sollte inzwischen klar sein, dass JavaScript von Haus aus keine solche Lösung bietet; hier sind die beiden nächstgelegenen Derivate, das nützlichste zuerst:

  1. Array.prototype.some(fn) bietet das gewünschte Verhalten des Anhaltens, wenn eine Bedingung erfüllt ist, gibt aber nur zurück, ob ein Element vorhanden ist; es ist nicht schwer, einige Tricks anzuwenden, wie zum Beispiel die Lösung, die von Bergi's Antwort .

  2. Array.prototype.filter(fn)[0] ist ein toller Einzeiler, aber am wenigsten effizient, denn man wirft weg N - 1 Elemente, nur um das zu bekommen, was Sie brauchen.

Traditionelle Suchmethoden in JavaScript zeichnen sich dadurch aus, dass sie den Index des gefundenen Elements anstelle des Elements selbst oder -1 zurückgeben. Dadurch wird vermieden, dass ein Rückgabewert aus dem Bereich aller möglichen Typen ausgewählt werden muss; ein Index kann nur eine Zahl sein und negative Werte sind ungültig.

Beide obigen Lösungen unterstützen auch nicht die Offset-Suche, also habe ich beschlossen, dies zu schreiben:

(function(ns) {
  ns.search = function(array, callback, offset) {
    var size = array.length;

    offset = offset || 0;
    if (offset >= size || offset <= -size) {
      return -1;
    } else if (offset < 0) {
      offset = size - offset;
    }

    while (offset < size) {
      if (callback(array[offset], offset, array)) {
        return offset;
      }
      ++offset;
    }
    return -1;
  };
}(this));

search([1, 2, NaN, 4], Number.isNaN); // 2
search([1, 2, 3, 4], Number.isNaN); // -1
search([1, NaN, 3, NaN], Number.isNaN, 2); // 3

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