Zastanawiam się, czy istnieje znany, wbudowany / elegancki sposób na znalezienie pierwszego elementu tablicy JS pasującego do danego warunku. Odpowiednikiem AC # będzie List.Find .
Do tej pory korzystałem z dwufunkcyjnej kombinacji:
// Returns the first element of an array that satisfies given predicate
Array.prototype.findFirst = function (predicateCallback) {
if (typeof predicateCallback !== 'function') {
return undefined;
}
for (var i = 0; i < arr.length; i++) {
if (i in this && predicateCallback(this[i])) return this[i];
}
return undefined;
};
// Check if element is not undefined && not null
isNotNullNorUndefined = function (o) {
return (typeof (o) !== 'undefined' && o !== null);
};
A potem mogę użyć:
var result = someArray.findFirst(isNotNullNorUndefined);
Ale skoro w ECMAScript jest wiele metod tablic funkcjonalnych , być może istnieje już coś takiego? Wyobrażam sobie, że wiele osób musi wdrażać takie rzeczy przez cały czas ...
javascript
arrays
Jakub P.
źródło
źródło
return (typeof (o) !== 'undefined' && o !== null);
do tegoreturn o != null;
. Są dokładnie równoważne.Odpowiedzi:
Od wersji ES6 istnieje natywna
find
metoda tablic; przestaje to wyliczać tablicę, gdy znajdzie ona pierwsze dopasowanie i zwraca wartość.Stara odpowiedź:
Muszę opublikować odpowiedź, aby zatrzymać te
filter
sugestie :-)Możesz użyć
some
metody Array do iteracji tablicy, dopóki warunek nie zostanie spełniony (a następnie zatrzymany). Niestety zwróci tylko to, czy warunek został spełniony tylko raz, a nie przez który element (lub przy jakim indeksie) został spełniony. Musimy więc trochę to zmienić:źródło
some()
z drugiej strony wraca natychmiast, co jest prawie szybsze w prawie wszystkich przypadkach niż rozwiązania filtrujące.Począwszy od ECMAScript 6, możesz
Array.prototype.find
do tego użyć . Jest to zaimplementowane i działa w Firefox (25.0), Chrome (45.0), Edge (12) i Safari (7.1), ale nie w Internet Explorerze ani innych starych lub rzadkich platformach .Na przykład poniższe wyrażenie ma wartość
106
.Jeśli chcesz teraz tego używać, ale potrzebujesz pomocy dla IE lub innych nieobsługujących przeglądarek, możesz użyć podkładki dystansowej. Polecam podkładkę es6 . MDN oferuje również podkładkę, jeśli z jakiegoś powodu nie chcesz wkładać całego podkładu es6 do swojego projektu. Aby uzyskać maksymalną kompatybilność, potrzebujesz podkładki es6-shim, ponieważ w przeciwieństwie do wersji MDN wykrywa ona błędne natywne implementacje
find
i zastępuje je (patrz komentarz rozpoczynający się od „Obejścia błędów w Array # find i Array # findIndex” oraz wiersze bezpośrednio po nim) .źródło
find
jest lepszy niż,filter
ponieważfind
zatrzymuje się natychmiast, gdy znajdzie element spełniający warunek, podczas gdyfilter
przechodzi przez wszystkie elementy, aby dać wszystkie dopasowane elementy.A co z użyciem filtra i uzyskaniem pierwszego indeksu z wynikowej tablicy?
źródło
.shift
tutaj?shift
jest to, że „wygląda elegancko”, ale w rzeczywistości jest bardziej mylące. Kto by pomyślał, że sprawdzenieshift()
bez argumentów byłoby tym samym, co wzięcie pierwszego elementu? Niejasne jest IMO. Dostęp do tablicy jest i tak szybszy: jsperf.com/array-access-vs-shift.shift()
nad[0]
jawnie podanym w ten sposób. Mimo to jest to alternatywa, z której możesz skorzystać, czy nie, trzymałbym się[0]
jednak.Do tej pory powinno być jasne, że JavaScript nie oferuje takiego rozwiązania natywnie; oto dwie najbliższe pochodne, najbardziej przydatne jako pierwsze:
Array.prototype.some(fn)
oferuje pożądane zachowanie zatrzymania po spełnieniu warunku, ale zwraca tylko to, czy element jest obecny; nietrudno zastosować pewne sztuczki, takie jak rozwiązanie oferowane przez odpowiedź Bergi .Array.prototype.filter(fn)[0]
tworzy świetną jednowarstwową, ale jest najmniej wydajna, ponieważ wyrzucaszN - 1
elementy tylko po to, aby uzyskać to, czego potrzebujesz.Tradycyjne metody wyszukiwania w JavaScript charakteryzują się zwracaniem indeksu znalezionego elementu zamiast samego elementu lub -1. Pozwala to uniknąć konieczności wybierania wartości zwracanej z domeny wszystkich możliwych typów; indeks może być tylko liczbą, a wartości ujemne są nieprawidłowe.
Oba powyższe rozwiązania nie obsługują również wyszukiwania offsetowego, więc postanowiłem napisać to:
źródło
Podsumowanie:
ES6
find()
find()
znajduje się na,Array.prototype
więc można go używać w każdej tablicy.find()
odbiera oddzwonienie, gdyboolean
testowany jest warunek. Funkcja zwraca wartość (nie indeks!)Przykład:
źródło
Jeśli używasz
underscore.js
, możesz użyć jegofind
iindexOf
funkcji, aby uzyskać dokładnie to, czego chcesz:Dokumentacja:
źródło
Począwszy od ES 2015,
Array.prototype.find()
zapewnia dokładnie taką funkcjonalność.W przypadku przeglądarek, które nie obsługują tej funkcji, sieć deweloperów Mozilla udostępniła wypełnienie (wklejone poniżej):
źródło
Array.prototype.find () właśnie to robi, więcej informacji: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
źródło
źródło
Mam inspirację z wielu źródeł w Internecie, aby czerpać z poniższego rozwiązania. Chciał wziąć pod uwagę zarówno pewną wartość domyślną, jak i zapewnić sposób na porównanie każdego wpisu dla ogólnego podejścia, które to rozwiązuje.
Zastosowanie: (podając wartość „Second”)
Realizacja:
źródło
Nie ma wbudowanej funkcji w Javascript do przeprowadzenia tego wyszukiwania.
Jeśli używasz jQuery, możesz zrobić
jQuery.inArray(element,array)
.źródło
$.inArray
nie zwraca wartości logicznej, (co zaskakujące!) Zwraca indeks pierwszego pasującego elementu. Jednak nadal nie robi tego, o co poprosił PO.Jest to mniej elegancki sposób, w którym
throw
wszystkie prawidłowe komunikaty o błędach (oparte naArray.prototype.filter
), ale przestaną iterować od pierwszego wynikuZatem przykłady są
Działa poprzez zakończenie
filter
za pomocąthrow
.źródło