Array.prototype.findIndex()
findIndex()
メソッドは、配列内の指定されたテスト関数を満たす最初の要素の位置を返します。テスト関数を満たす要素がない場合を含め、それ以外の場合は -1
を返します。
find()
メソッドも参照してください。このメソッドは、配列内で見つかった要素の位置ではなく、値 を返します。
構文
arr.findIndex(callback( element[, index[, array]] )[, thisArg])
引数
callback
-
配列内のそれぞれの値に対して実行される関数で、条件を満たす要素が発見されたことを示す
true
が返るまで続けられます。3つの引数を取ります。
element
- 配列内で現在処理されている要素。
index
省略可- 配列内で現在処理されている要素の位置。
array
省略可findIndex()
を呼び出した元の配列。
thisArg
省略可- 任意で、
callback
を実行する時にthis
として使うオブジェクト。
返値
テストを満たした配列の要素の位置を返します。それ以外の場合は、 -1
を返します。
解説
findIndex()
メソッドは、配列のそれぞれの位置に対して callback
を1回ずつ呼び出し、 callback
が真値を返すものを見つけるまで繰り返します。
そのような要素が見つかると、 findIndex()
はすぐにその要素の位置を返します。 callback
が真値を返すと (または配列の length
が 0
であると)、 findIndex()
は -1
を返します。
極端な場合の警告: Array.some()
などの他の配列メソッドとは異なり、 callback
は値が割り当てられていない位置でも実行されます。
callback
は3つの引数で呼び出されます。
- その要素の値
- その要素の位置
- 走査されている配列オブジェクト
findIndex
に thisArg
引数を与えた場合、各 callback
の呼び出し時に、その与えたオブジェクトが、this
として使用されます。この引数を省略した場合、this
は undefined
になります。
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
仕様書
ブラウザーの互換性
BCD tables only load in the browser