322

特定の条件に一致するJS配列の最初の要素を見つけるための既知の組み込み/エレガントな方法があるかどうか疑問に思っています。AC# に相当するのはList.Findです。

これまでのところ、次のような 2 つの機能のコンボを使用してきました。

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

そして、私は使用することができます:

var result = someArray.findFirst(isNotNullNorUndefined);

しかし、ECMAScript には非常に多くの関数型配列メソッドがあるため、このようなものが既に存在するのではないでしょうか? 多くの人がこのようなものを常に実装しなければならないと思います...

4

13 に答える 13

372

ES6 以降、配列用のネイティブfindメソッドがあります。これは、最初の一致を見つけて値を返すと、配列の列挙を停止します。

const result = someArray.find(isNotNullNorUndefined);

古い答え:

これらの提案を止めるには、回答を投稿する必要がありますfilter:-)

ECMAScript には非常に多くの関数型配列メソッドがあるため、このようなものが既に存在するのではないでしょうか?

someArray メソッドを使用して、条件が満たされるまで (そして停止するまで) 配列を繰り返すことができます。残念ながら、どの要素 (またはどのインデックス) で条件が満たされたかではなく、条件が 1 回満たされたかどうかのみが返されます。したがって、少し修正する必要があります。

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);
于 2013-08-29T20:20:27.887 に答える
126

ECMAScript 6 の時点で、これを使用できますArray.prototype.find。これは Firefox (25.0)、Chrome (45.0)、Edge (12)、および Safari (7.1) で実装され、動作しますが、Internet Explorer やその他の古いプラットフォームや珍しいプラットフォームでは機能しません

たとえば、x以下は106次のとおりです。

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

これを今すぐ使用したいが、IE またはその他のサポートされていないブラウザーのサポートが必要な場合は、shim を使用できます。es6-shimをお勧めします。何らかの理由で es6-shim 全体をプロジェクトに入れたくない場合、 MDN はshimも提供します。最大限の互換性を得るには、es6-shim が必要です。これは、MDN バージョンとは異なり、バグのあるネイティブ実装を検出して上書きするためです ( 「Array#find および Array#findIndex のバグの回避」findで始まるコメントとその直後の行を参照してください) 。 .

于 2014-02-03T23:33:11.183 に答える
74

フィルターを使用して、結果の配列から最初のインデックスを取得するのはどうですか?

var result = someArray.filter(isNotNullNorUndefined)[0];
于 2013-08-28T15:54:37.737 に答える
40

概要:

  • ブール条件に一致する配列内の最初の要素を見つけるには、ES6 find()
  • find()が配置されArray.prototypeているため、すべてのアレイで使用できます。
  • find()boolean条件がテストされるコールバックを受け取ります。関数は値を返します(インデックスではありません!)

例:

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

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

console.log(found);   //  56

于 2018-08-19T11:46:10.543 に答える
15

JavaScript がそのようなソリューションをネイティブに提供していないことは明らかです。最も近い 2 つの導関数を次に示します。最も有用なものが最初です。

  1. Array.prototype.some(fn)条件が満たされたときに停止するという望ましい動作を提供しますが、要素が存在するかどうかのみを返します。Bergi's answerによって提供されるソリューションなど、いくつかの策略を適用することは難しくありません。

  2. Array.prototype.filter(fn)[0]優れたワンライナーN - 1になりますが、必要なものを取得するためだけに要素を破棄するため、効率が最も低くなります。

JavaScript の従来の検索方法は、要素自体または -1 の代わりに、見つかった要素のインデックスを返すという特徴があります。これにより、可能なすべての型のドメインから戻り値を選択する必要がなくなります。インデックスは数値のみであり、負の値は無効です。

上記の両方のソリューションはオフセット検索もサポートしていないため、次のように書くことにしました。

(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
于 2013-09-17T04:57:48.353 に答える
9

を使用している場合underscore.jsは、その関数findindexOf関数を使用して、必要なものを正確に取得できます。

var index = _.indexOf(your_array, _.find(your_array, function (d) {
    return d === true;
}));

ドキュメンテーション:

于 2013-09-17T03:12:19.187 に答える
4

ES 2015 の時点で、Array.prototype.find()この正確な機能を提供します。

この機能をサポートしていないブラウザーの場合、Mozilla Developer Network はポリフィルを提供しています(以下に貼り付けます)。

if (!Array.prototype.find) {
  Array.prototype.find = 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++) {
      value = list[i];
      if (predicate.call(thisArg, value, i, list)) {
        return value;
      }
    }
    return undefined;
  };
}
于 2016-05-02T18:48:41.037 に答える
3

Array.prototype.find() はまさにそれを行います。詳細: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find

于 2016-02-22T16:28:03.183 に答える
0

インターネット上の複数のソースからインスピレーションを得て、以下のソリューションを導き出しました。いくつかのデフォルト値を考慮し、これが解決する一般的なアプローチの各エントリを比較する方法を提供したいと考えていました。

使用法: (値「Second」を指定)

var defaultItemValue = { id: -1, name: "Undefined" };
var containers: Container[] = [{ id: 1, name: "First" }, { id: 2, name: "Second" }];
GetContainer(2).name;

実装:

class Container {
    id: number;
    name: string;
}

public GetContainer(containerId: number): Container {
  var comparator = (item: Container): boolean => {
      return item.id == containerId;
    };
    return this.Get<Container>(this.containers, comparator, this.defaultItemValue);
  }

private Get<T>(array: T[], comparator: (item: T) => boolean, defaultValue: T): T {
  var found: T = null;
  array.some(function(element, index) {
    if (comparator(element)) {
      found = element;
      return true;
    }
  });

  if (!found) {
    found = defaultValue;
  }

  return found;
}
于 2019-08-07T16:49:13.520 に答える
-2

この検索を実行する Javascript の組み込み関数はありません。

jQuery を使用している場合は、jQuery.inArray(element,array).

于 2012-05-04T23:22:55.177 に答える