Array.prototype.find()


Metoda find() zwraca pierwszy element tablicy, który spełnia warunek podanej funkcji testującej.
  • Jeśli potrzebujesz indeksu znalezionego elementu w tablicy, użyj findIndex().
  • Jesli potrzebujesz indeksu wartości, użyj Array.prototype.indexOf(). (Jest to podobne do findIndex(), ale sprawdza każdy element tablicy pod kątem równości z zadaną wartością, zamiast używać funkcji testującej.)
  • Jeśli chcesz sprawdzić, czy wartość istnieje w tablicy, użyj Array.prototype.includes(). Tutaj także sprawdzana jest równość elementu z zadaną wartością zamiast używania funkcji testującej.
  • Jeśli chcesz znaleźć dowolny element, który spełnia warunek funkcji testującej, użyj Array.prototype.some().

Składnia

arr.find(callback[, thisArg])

Parametry

callback
Funkcja do wykonania przy każdym elemencie tablicy, przyjmująca trzy wartości:
element
Element obecnie przetwarzany przez funkcję.
index
Indeks obecnie przetwarzanego elementu.
array
Tablica, na której wywołano funkcję find.
thisArg
Opcjonalny. Obiekt, który będzie się znajdował pod this w czasie wykonywania funkcji callback.

Zwracana wartość

Wartość pierwszego elementu w tablicy, spełniającego warunek funkcji testującej.
W przeciwnym wypadku: undefined.

Opis

Metoda find wywołuje funkcję callback raz dla każdego indeksu tablicy, dopóki nie znajdzie takiego elementu, dla którego callback zwraca wartość true. Wówczas find natychmiast zwraca wartość tego elementu. W przeciwnym razie, gdy żaden z elementów nie spełni warunków funkcji testującej, find zwraca undefined.

callback jest wywoływany dla każdego indeksu tablicy, nie tylko tych z przypisanymi wartościami. Oznacza to, że może to być mniej efektywne w przypadku tablic rzadkich, w porównaniu z metodami, które odwiedzają jedynie indeksy z przypisanymi wartościami.

Jeśli parametr thisArgjest przekazany do find, będzie użyty jako wartość this w każdym wywołaniu callback. Jeśli parametr ten nie jest przekazany, używana jest wartość undefined.

Metoda find nie modyfikuje tablicy, na której jest wywoływana, ale może to robić funkcja przekazana do callback. Jeśli tak się stanie, elementy przetwarzane przez find są ustawiane przed pierwszym wywołaniem funkcji callback. Zatem:

  • callback nie odwiedzi żadnych elementów dodanych do tablicy po rozpoczęciu wywowłania find.
  • Jeśli istniejący, jeszcze nieodwiedzony element tablicy jest zmieniony przez callback, jego wartość przekazana do callback będzie wartością w momencie, w którym find odwiedza indeks tego elementu.
  • Elementy usunięte dalej są odwiedzane.

Polyfill

Metoda ta została dodana do specyfikacji ECMAScript 2015 i może nie być jeszcze dostępna we wszystkich implementacjach języka JavaScript.  Niemniej jednak, możesz użyć polyfillArray.prototype.find z poniższym fragmentem kodu:

// 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
  });
}

Jeśli potrzebujesz wspierać naprawdę przestarzałe silniki JavaScript, które nie wspierająt Object.defineProperty, najlepiej w ogóle nie używać polyfill z Array.prototype, gdyż nie da się go uczynić niewyliczeniowym.

Przykłady

Wyszukiwanie obiektu w tablicy na podstawie jednej z jego własności

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 }

Użycie funkcji strzałkowej i destrukturyzacja

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 }

Wyszukiwanie liczby pierwszej w tablicy

Poniższy przykładowy kod znajduje element tablicy będący liczbą pierwszą (lub zwraca undefined jeśli w tablicy nie ma liczby pierwszej):

function czyPierwsza(element, indeks, tablica) {
  let start = 2;
  while (start <= Math.sqrt(element)) {
    if (element % start++ < 1) {
      return false;
    }
  }
  return element > 1;
}

console.log([4, 6, 8, 12].find(czyPierwsza)); // undefined, nie znaleziono
console.log([4, 5, 8, 12].find(czyPierwsza)); // 5

Poniższy przykład pokazuje, że nieistniejące i usunięte elementy odwiedzane, oraz że wartość przekazana do callback jest ich wartością, kiedy są odwiedzane:

// Zadeklaruj tablicę bez elementów przy indeksach 2, 3 i 4
const array = [0,1,,,,5,6];

// Pokazuje wszystkie indeksy, nie tylko te z przypisanymi wartościami
array.find(function(value, index) {
  console.log('Odwiedzono indeks ', index, ' z wartością ', value); 
});

// Pokazuje wszystkie indeksy, włączając usunięte
array.find(function(value, index) {
  // Usuń element 5 w pierwszej iteracji
  if (index === 0) {
    console.log('Usuwanie array[5] z wartością ', array[5]);
    delete array[5];
  }
  // Element 5 jest wciąż odwiedzany, choć został usunięty
  console.log('Odwiedzono indeks ', index, ' z wartością ', value); 
});
// Oczekiwane wyjście:
// Usuwanie array[5] z wartością 5 
// Odwiedzono indeks 0 z wartością 0 
// Odwiedzono indeks 1 z wartością 1 
// Odwiedzono indeks 2 z wartością undefined 
// Odwiedzono indeks 3 z wartością undefined 
// Odwiedzono indeks 4 z wartością undefined 
// Odwiedzono indeks 5 z wartością undefined 
// Odwiedzono indeks 6 z wartością 6

Specyfikacje

Specyfikacja Status Komentarz
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Array.prototype.find' in that specification.
Standard Pierwotna definicja.

Wsparcie przeglądarek

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help!
Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support 45.0 25.0 (25.0) No support No support 7.1
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support No support No support 25.0 (25.0) No support No support iOS 8

Zobacz też