find()
メソッドは、提供されたテスト関数を満たす配列内の 最初の要素 の 値 を返します。
The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.
このデモのソースファイルは GitHub リポジトリに格納されています。デモプロジェクトに協力したい場合は、https://github.com/mdn/interactive-examples をクローンしてプルリクエストを送信してください。
- 配列内で見つかった要素の添字が必要な場合は、
findIndex()
を使用してください。 - 値の添字を検索する必要がある場合は、
Array.prototype.indexOf()
を使用してください。(findIndex()
と似ていますが、それぞれの要素の等価性はテスト関数ではなく値でチェックします。) - 配列内に値が存在するかどうかを調べる必要がある場合は、
Array.prototype.includes()
を使用してください。 - 指定したテスト関数を満たす要素があるかどうかを調べる必要がある場合は、
Array.prototype.some()
を使用してください。
構文
arr.find(callback(element[, index[, array]])[, thisArg])
引数
callback
- 配列内の各要素に対して実行する関数で、次の 3 つの引数を取ります。
element
- 配列内で現在処理されている要素です。
index
省略可- 配列内で現在処理されている要素の添字 (位置) です。
array
省略可find
を呼び出した元の配列です。
thisArg
省略可callback
内でthis
として使われるオブジェクトです。
返値
配列の中で、提供されたテスト関数を満足する最初の要素の値です。見つからなかった場合は undefined
を返します。
解説
find
メソッドは、配列のそれぞれの添字に対して一度ずつ、callback
関数を実行し、callback
関数が truthy な値を返すまで繰り返します。その場合、find
は直ちにその要素の値を返します。そうでなければ、find
は undefined
を返します。
callback
は、値が割り当てられているものに限らず、配列中のすべての添字に対して呼び出されます。すなわち、疎配列では値が割り当てられているもののみを呼び出すメソッドに比べて効率的ではないことを意味します。
thisArg
引数が find
に与えられた場合、callback
の呼び出しのたびに、その内部で this
値として使用されます。この引数を省略した場合は undefined
が使用されます。
find
は、呼び出した配列を変更 (mutate) しませんが、callback
で提供された関数は変更する可能性があります。その場合、find
によって処理される各要素は、最初に callback
が呼び出される前に設定されます。したがって、
callback
はfind
の呼び出しが始まった後に追加された要素に対しては実行されません。- 配列の、既存のまだ呼び出していない要素が
callback
によって変更された場合、callback
に渡される値はfind
がその要素の添字を処理した時点での値になります。 削除
された要素も処理されます。
ポリフィル
このメソッドは、ECMAScript 2015 仕様書で追加されたものであり、すべての JavaScript 実装環境で使用できるとは限りません。しかし、Array.prototype.find
のポリフィルを以下のスニペットで使用できます。
// https://tc39.github.io/ecma262/#sec-array.prototype.find
if (!Array.prototype.find) {
Object.defineProperty(Array.prototype, 'find', {
value: function(predicate) {
// 1. Let O be ? ToObject(this value).
if (this == null) {
throw 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 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 kValue.
var kValue = o[k];
if (predicate.call(thisArg, kValue, k, o)) {
return kValue;
}
// e. Increase k by 1.
k++;
}
// 7. Return undefined.
return undefined;
},
configurable: true,
writable: true
});
}
Object.defineProperty
に対応していない、本当に古い JavaScript エンジンに対応する必要がある場合は、列挙不可に設定することができないため、Array.prototype
のポリフィルをまったく使用しないのが最善です。
例
配列内のオブジェクトをプロパティの一つで検索
const inventory = [
{name: 'apples', quantity: 2},
{name: 'bananas', quantity: 0},
{name: 'cherries', quantity: 5}
];
function isCherries(fruit) {
return fruit.name === 'cherries';
}
console.log(inventory.find(isCherries));
// { name: 'cherries', quantity: 5 }
アロー関数と分割の使用
const inventory = [
{name: 'apples', quantity: 2},
{name: 'bananas', quantity: 0},
{name: 'cherries', quantity: 5}
];
const result = inventory.find( ({ name }) => name === 'cherries' );
console.log(result) // { name: 'cherries', quantity: 5 }
配列内の素数の検索
次の例は、配列内の素数を探します (配列内に素数が見つからない場合は undefined
を返します)。
function isPrime(element, index, array) {
let start = 2;
while (start <= Math.sqrt(element)) {
if (element % start++ < 1) {
return false;
}
}
return element > 1;
}
console.log([4, 6, 8, 12].find(isPrime)); // undefined, 見つからない
console.log([4, 5, 8, 12].find(isPrime)); // 5
以下の例は存在せず削除された要素が処理されること、コールバックに渡される値が処理時点での値であることを示しています。
// 添字が 2, 3, 4 の位置に要素がない配列を宣言
const array = [0,1,,,,5,6];
// 値が割り当てられているものに限らず、すべての添字を表示
array.find(function(value, index) {
console.log('Visited index ', index, ' with value ', value);
});
// 削除されたものを含め、すべての添字を表示
array.find(function(value, index) {
// 初回で要素 5 を削除
if (index === 0) {
console.log('Deleting array[5] with value ', array[5]);
delete array[5];
}
// 要素 5 は削除されても処理される
console.log('Visited index ', index, ' with value ', value);
});
// 期待される出力:
// Deleting array[5] with value 5
// Visited index 0 with value 0
// Visited index 1 with value 1
// Visited index 2 with value undefined
// Visited index 3 with value undefined
// Visited index 4 with value undefined
// Visited index 5 with value undefined
// Visited index 6 with value 6
仕様
ブラウザー実装状況
BCD tables only load in the browser
関連情報
Array.prototype.findIndex()
– インデックスを見つけて返すArray.prototype.includes()
– 配列内に値が存在するかどうかをテストするArray.prototype.filter()
– マッチしない要素をすべて削除するArray.prototype.every()
– すべての要素をテストするArray.prototype.some()
– 1つの要素が一致するまでテストする