Array.prototype.find()

Метод find() повертає значення першого елемента в масиві, що задовільняє передану функцію тестування. Інакше вертається undefined.

Зверніть увагу також на метод findIndex(), що натомість повертає індекс знайденого елемента масиву, а не значення.

Якщо вам необхідно знайти позицію елемента або дізнатись, чи існує елемент в масиві, використовуйте Array.prototype.indexOf() або Array.prototype.includes().

Синтаксис

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

Параметри

callback
Функція, що виконується для кожного значення в масиві і приймає три аргументи:
element
Значення поточного елемента масиву.
indexOptional
Індекс поточного елемента масиву.
arrayOptional
Масив, для якого було викликано find.
thisArg Optional
Необов'язковий об'єкт, що використовується в якості this при виконанні callback.

Вертає

Значення першого елемента в масиві, який задовольняє надану перевірочну функцію. Інакше повертається undefined.

Опис

Метод find виконує функцію callback один раз для кожного елемента в масиві, аж поки не буде знайдено такий, для якого callback повертає true. Щойно такий елемент знайдено, find одразу ж повертає значення цього елемента. В іншому випадку, find  повертає undefined. Функція callback викликається для кожного індексу масиву з 0 по length - 1 і виконується для усіх елементів, не лише для тих, які мають присвоєні значення. Це означає, що цей метод може бути менш ефективним для розріджених масивів у порівнянні з методами, які обробляють лише ті, елементи, яким присвоєні значення.

Функція callback викликається з трьома аргументами: значення елемента, індекс елемента і об'єкт Array, перебір якого здійснюється.

Якщо параметр thisArg передано до find, його буде використано як this для кожного виклику callback. Якщо його не передано, тоді використовуватиметься undefined.

Метод find() не змінює масив, для якого викликається.

Діапазон елементів, що їх має обробити find, визначається ще до першого виклику функції callback. Тому callback не обробляє елементи, додані до масиву після того, як почалося виконання find. Якщо існуючий, ще не опрацьований елемент масиву, змінюється функцією callback, його значення, що передається до callback, буде значенням на той момент, коли find доходить до індексу цього елемента. Видалені елементи все одно опрацьовуються.

Приклади

Знайти об'єкт в масиві за однією з його властивостей

var inventory = [
    {name: 'яблука', quantity: 2},
    {name: 'банани', quantity: 0},
    {name: 'вишні', quantity: 5}
];

function findCherries(fruit) { 
    return fruit.name === 'вишні';
}

console.log(inventory.find(findCherries));
// виводить { name: 'вишні', quantity: 5 }

Використання стрілочної функції ES2015

const inventory = [
    {name: 'яблука', quantity: 2},
    {name: 'банани', quantity: 0},
    {name: 'вишні', quantity: 5}
];

const result = inventory.find( fruit => fruit.name === 'вишні' );

console.log(result) // { name: 'вишні', quantity: 5 }

Знайти просте число у масиві

Наступний приклад знаходить елемент у масиві, який є простим числом (або повертає undefined, якщо простого числа немає):

function isPrime(element, index, array) {
  var start = 2;
  while (start <= Math.sqrt(element)) {
    if (element % start++ < 1) {
      return false;
    }
  }
  return element > 1;
}

[4, 6, 8, 12].find(isPrime);  // вертає undefined, простих чисел не знайдено
[4, 5, 8, 12].find(isPrime);  // вертає 5

Наступні приклади демонструють, що неіснуючі та видалені елементи теж опрацьовуються, і що значення, передане до функції зворотного виклику - це їхнє значення на момент перевірки.

// Створити масив без елементів за індексами 2, 3 та 4
const array = [0,1,,,,5,6];

// Виводить всі індекси, не лише ті, які мають присвоєні значення
array.find(function(value, index) {
  console.log('Індекс ' + index + ' має значення ' + value);
});

// Виводить всі індекси, в тому числі видалені
array.find(function(value, index) {

  // Видалити елемент 5 в першій ітерації
  if (index == 0) {
    console.log('Видалення елемента array[5] зі значенням ' + array[5]);
    delete array[5];
  }
  // Елемент 5 перевіряється, хоч і був видалений
  console.log('Індекс ' + index + ' має значення ' + value);
});
// очікуваний результат:
// Видалення елемента array[5] зі значенням 5
// Індекс 0 має значення 0
// Індекс 1 має значення 1
// Індекс 2 має значення undefined
// Індекс 3 має значення undefined
// Індекс 4 має значення undefined
// Індекс 5 має значення undefined
// Індекс 6 має значення 6

Запасний варіант (поліфіл)

Цей метод був доданий у 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. Нехай O дорівнює ? ToObject(this value).
      if (this == null) {
        throw new TypeError('"this" is null or not defined');
      }

      var o = Object(this);

      // 2. Нехай len дорівнює ? ToLength(? Get(O, "length")).
      var len = o.length >>> 0;

      // 3. Якщо IsCallable(predicate) дорівнює false, викинути виняток TypeError.
      if (typeof predicate !== 'function') {
        throw new TypeError('предикат має бути функцією');
      }

      // 4. Якщо надано thisArg, нехай T дорівнює thisArg; інакше нехай T дорівнює undefined.
      var thisArg = arguments[1];

      // 5. Нехай k дорівнює 0.
      var k = 0;

      // 6. Повторювати, поки k < len
      while (k < len) {
        // a. Нехай Pk дорівнює ! ToString(k).
        // b. Нехай kValue дорівнює ? Get(O, Pk).
        // c. Нехай testResult дорівнює ToBoolean(? Call(predicate, T, « kValue, k, O »)).
        // d. Якщо testResult дорівнює true, повернути kValue.
        var kValue = o[k];
        if (predicate.call(thisArg, kValue, k, o)) {
          return kValue;
        }
        // e. Збільшити k на 1.
        k++;
      }

      // 7. Повернути undefined.
      return undefined;
    }
  });
}

Якщо вам потрібно забезпечити підтримку вкрай застарілих рушіїв JavaScript, в яких відсутня підтримка Object.defineProperty, було б краще взагалі не додавати методів до Array.prototype через відсутність можливості заборонити їх перебір.

Специфікації

Специфікації Статус Коментар
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Array.prototype.find' in that specification.
Standard Первинне визначення.
ECMAScript Latest Draft (ECMA-262)
The definition of 'Array.prototype.find' in that specification.
Draft

Підтримка веб-переглядачами

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
findChrome Full support 45Edge Full support 12Firefox Full support 25IE No support NoOpera Full support 32Safari Full support 8WebView Android Full support YesChrome Android Full support 45Firefox Android Full support 4Opera Android Full support YesSafari iOS Full support 8Samsung Internet Android Full support Yesnodejs Full support 4.0.0
Full support 4.0.0
Full support 0.12
Disabled
Disabled From version 0.12: this feature is behind the --harmony runtime flag.

Legend

Full support  
Full support
No support  
No support
User must explicitly enable this feature.
User must explicitly enable this feature.

Див. також