--- title: Array.prototype.find() slug: Web/JavaScript/Reference/Global_Objects/Array/find tags: - Array - ECMAScript 2015 - JavaScript - Method - Prototype - Reference - polyfill translation_of: Web/JavaScript/Reference/Global_Objects/Array/find ---
{{JSRef}}

find() メソッドは、提供されたテスト関数を満たす配列内の 最初の要素 を返します。

{{EmbedInteractiveExample("pages/js/array-find.html")}}

構文

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

引数

callback
配列内の各要素に対して実行する関数で、次の 3 つの引数を取ります。
element
配列内で現在処理されている要素です。
index {{optional_inline}}
配列内で現在処理されている要素の添字 (位置) です。
array {{optional_inline}}
find を呼び出した元の配列です。
thisArg {{optional_inline}}
callback 内で {{jsxref("Operators/this", "this")}} として使われるオブジェクトです。

返値

配列の中で、提供されたテスト関数を満足する最初の要素です。見つからなかった場合は {{jsxref("undefined")}} を返します。

解説

find メソッドは、配列のそれぞれの添字に対して一度ずつ、callback 関数を実行し、callback 関数が {{glossary("truthy")}} な値を返すまで繰り返します。その場合、find は直ちにその要素の値を返します。そうでなければ、find は {{jsxref("undefined")}} を返します。

callback は、値が割り当てられているものに限らず、配列中のすべての添字に対して呼び出されます。すなわち、疎配列では値が割り当てられているもののみを呼び出すメソッドに比べて効率的ではないことを意味します。

thisArg 引数が find に与えられた場合、callback の呼び出しのたびに、その内部で this 値として使用されます。この引数を省略した場合は {{jsxref("undefined")}} が使用されます。

find は、呼び出した配列を変更 (mutate) しませんが、callback で提供された関数は変更する可能性があります。その場合、find によって処理される各要素は、最初に callback が呼び出される前に設定されます。したがって、

ポリフィル

このメソッドは、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 }

配列内の素数の検索

次の例は、配列内の素数を探します (配列内に素数が見つからない場合は {{jsxref("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

仕様

仕様書
{{SpecName('ESDraft', '#sec-array.prototype.find', 'Array.prototype.find')}}

ブラウザー実装状況

{{Compat("javascript.builtins.Array.find")}}

関連情報