Array.prototype.findIndex()

findIndex() メソッドは、配列内の指定されたテスト関数を満たす最初の要素の位置を返します。テスト関数を満たす要素がない場合を含め、それ以外の場合は -1 を返します。

find() メソッドも参照してください。このメソッドは、配列内で見つかった要素の位置ではなく、 を返します。

構文

arr.findIndex(callback( element[, index[, array]] )[, thisArg])

引数

callback

配列内のそれぞれの値に対して実行される関数で、条件を満たす要素が発見されたことを示す true が返るまで続けられます。

3つの引数を取ります。

element
配列内で現在処理されている要素。
index Optional
配列内で現在処理されている要素の位置。
array Optional
findIndex() を呼び出した元の配列。
thisArg Optional
任意で、 callback を実行する時に this として使うオブジェクト。

返値

テストを満たした配列の要素の位置を返します。それ以外の場合は、 -1 を返します。

解説

findIndex() メソッドは、配列のそれぞれの位置に対して callback を1回ずつ呼び出し、 callback真値を返すものを見つけるまで繰り返します。

そのような要素が見つかると、 findIndex() はすぐにその要素の位置を返します。 callback が真値を返すと (または配列の length0 であると)、 findIndex()-1 を返します。

極端な場合の警告: Array.some() などの他の配列メソッドとは異なり、 callback は値が割り当てられていない位置でも実行されます。

callback は3つの引数で呼び出されます。

  1. その要素の値
  2. その要素の位置
  3. 走査されている配列オブジェクト

findIndexthisArg 引数を与えた場合、各 callback の呼び出し時に、その与えたオブジェクトが、this として使用されます。この引数を省略した場合、thisundefined になります。

findIndex() で処理される要素の範囲は、 callback が最初に呼び出される前に設定されます。 callback は最初の findIndex() の呼び出し以降に配列に追加された要素は処理しません。配列内で未処理の既存の要素が callback によって変更された場合、 callback へ渡される値は findIndex() がその要素の位置を処理する時点での値になります。

削除された値も処理対象になります。

ポリフィル

// https://tc39.github.io/ecma262/#sec-array.prototype.findindex
if (!Array.prototype.findIndex) {
  Object.defineProperty(Array.prototype, 'findIndex', {
    value: function(predicate) {
     // 1. Let O be ? ToObject(this value).
      if (this == null) {
        throw new TypeError('"this" is null or not defined');
      }

      var o = Object(this);

      // 2. Let len be ? ToLength(? Get(O, "length")).
      var len = o.length >>> 0;

      // 3. If IsCallable(predicate) is false, throw a TypeError exception.
      if (typeof predicate !== 'function') {
        throw new TypeError('predicate must be a function');
      }

      // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
      var thisArg = arguments[1];

      // 5. Let k be 0.
      var k = 0;

      // 6. Repeat, while k < len
      while (k < len) {
        // a. Let Pk be ! ToString(k).
        // b. Let kValue be ? Get(O, Pk).
        // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
        // d. If testResult is true, return k.
        var kValue = o[k];
        if (predicate.call(thisArg, kValue, k, o)) {
          return k;
        }
        // e. Increase k by 1.
        k++;
      }

      // 7. Return -1.
      return -1;
    },
    configurable: true,
    writable: true
  });
}

もし、本当に Object.defineProperty に対応していない古い JavaScript エンジンに対応する必要があるのであれば、 Array.prototype メソッドに対してポリフィルを使用しないようにしないと、これらを列挙不可能にすることができません。

配列内の素数の位置を検索する

次の例では、配列の中で素数の入った最初の要素の位置を返し、素数が見つからなかった場合は -1 を返します。

function isPrime(num) {
  for (let i = 2; num > i; i++) {
    if (num % i == 0) {
      return false;
    }
  }
  return num > 1;
}

console.log([4, 6, 8, 9, 12].findIndex(isPrime)); // -1, not found
console.log([4, 6, 7, 9, 12].findIndex(isPrime)); // 2 (array[2] is 7)

アロー関数を使用して位置を検索する

次の例では、アロー関数を使用してフルーツの位置を検索しています。

const fruits = ["apple", "banana", "cantaloupe", "blueberries", "grapefruit"];

const index = fruits.findIndex(fruit => fruit === "blueberries");

console.log(index); // 3
console.log(fruits[index]); // blueberries

仕様書

仕様書
ECMAScript (ECMA-262)
Array.prototype.findIndex の定義

ブラウザーの互換性

Update compatibility data on GitHub
デスクトップモバイルサーバー
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung InternetNode.js
findIndexChrome 完全対応 45Edge 完全対応 12Firefox 完全対応 25IE 未対応 なしOpera 完全対応 32Safari 完全対応 8WebView Android 完全対応 45Chrome Android 完全対応 45Firefox Android 完全対応 4Opera Android 完全対応 32Safari iOS 完全対応 8Samsung Internet Android 完全対応 5.0nodejs 完全対応 4.0.0
完全対応 4.0.0
完全対応 0.12
無効
無効 From version 0.12: this feature is behind the --harmony runtime flag.

凡例

完全対応  
完全対応
未対応  
未対応
ユーザーが明示的にこの機能を有効にしなければなりません。
ユーザーが明示的にこの機能を有効にしなければなりません。

関連情報