Chciałbym zrozumieć najlepszy sposób filtrowania tablicy ze wszystkich elementów innej . Próbowałem z funkcją filtru, ale nie przychodzi mi do głowy, jak nadać jej wartości, które chcę usunąć.
Coś jak:
var array = [1,2,3,4];
var anotherOne = [2,4];
var filteredArray = array.filter(myCallback);
// filteredArray should now be [1,3]
function myCallBack(){
return element ! filteredArray;
//which clearly can't work since we don't have the reference <,<
}
jeśli funkcja filtrująca nie jest użyteczna, jak byś to zaimplementował?
Edycja: sprawdziłem możliwe zduplikowane pytanie i może być przydatne dla tych, którzy łatwo rozumieją JavaScript. Odpowiedź zaznaczona jako dobra ułatwia sprawę.
javascript
arrays
filter
Koop4
źródło
źródło
return arrTwo.indexOf(e) === -1;
kodu:var filteredArr = firstArr.filter(el => secondArr.indexOf(el) === -1);
Odpowiedzi:
Możesz użyć
this
parametrufilter()
funkcji, aby uniknąć przechowywania tablicy filtrów w zmiennej globalnej.źródło
this
.this
zawsze wydaje się być nieokreślone ?! DziwneZrobiłbym co następuje;
źródło
const filteredResults = this.state.cards.filter( result => !this.state.filterOut.includes(result.category) )
Odfiltrowywanie tablicy obiektów na podstawie tablicy wartości w komponencie reagującym: gdzie this.state.cards w tablicy obiektów, a this.state.filterOut jest tablicą wartości odpowiadających kluczowi „category” w obiektach, które Chciałem usunąć.W wywołaniu zwrotnym sprawdzasz, czy każda wartość
array
jest wanotherOne
https://jsfiddle.net/0tsyc1sx/
Jeśli używasz
lodash.js
, użyj_.difference
Próbny
Jeśli masz tablicę obiektów:
Demo tablica obiektów
Demo tablica różnic obiektów z lodash
źródło
id
wanotherOne_el.id == array_el.id
z kluczem cokolwiek masz w swoim własnym obiekcie. Powinieneś zdobyć wiedzę na temat tablic i obiektów w javascript, pomoże ci to lepiej zrozumieć odpowiedźźródło
Poniższy kod to najprostszy sposób filtrowania tablicy w odniesieniu do innej tablicy. Obie tablice mogą zawierać obiekty zamiast wartości.
Wynik:
[3, 6]
źródło
Jest wiele odpowiedzi na Twoje pytanie, ale nie widzę nikogo używającego wyrażenia lambda:
źródło
Wszystkie powyższe rozwiązania "działają", ale są mniej niż optymalne dla wydajności i wszystkie podchodzą do problemu w ten sam sposób, czyli liniowe przeszukiwanie wszystkich wpisów w każdym punkcie przy użyciu Array.prototype.indexOf lub Array.prototype.includes . Znacznie szybszym rozwiązaniem (o wiele szybszym nawet niż wyszukiwanie binarne dla większości przypadków) byłoby posortowanie tablic i przeskoczenie do przodu w trakcie, jak pokazano poniżej. Jednak jedną wadą jest to, że wymaga to, aby wszystkie wpisy w tablicy były liczbami lub łańcuchami. Jednak w niektórych rzadkich przypadkach wyszukiwanie binarne może być szybsze niż progresywne wyszukiwanie liniowe. Przypadki te wynikają z faktu, że moje progresywne wyszukiwanie liniowe ma złożoność O (2n 1 + n 2 ) (tylko O (n 1+ n 2 ) w szybszej wersji C / C ++) (gdzie n 1 to przeszukiwana tablica an 2 to tablica filtrów), podczas gdy wyszukiwanie binarne ma złożoność O (n 1 ceil (log 2 n 2 )) ( ceil = zaokrąglenie w górę - do górnego pułapu ) i wreszcie indeks wyszukiwania ma wysoce zmienną złożoność między O (n 1 ) a O (n 1 n 2 ) , uśredniając do O (n 1 ceil (n 2) ÷ 2)) . Zatem indexOf będzie średnio najszybszy tylko w przypadkach(n 1 , n 2 ) równa {1,2} , {1,3} lub {x, 1 | x∈N} . Jednak nadal nie jest to idealna reprezentacja nowoczesnego sprzętu. IndexOf jest natywnie zoptymalizowany w najszerszym możliwym zakresie, jaki można sobie wyobrazić w większości nowoczesnych przeglądarek, dzięki czemu podlega prawom przewidywania gałęzi . Tak więc, jeśli przyjmiemy to samo założenie na indexOf, co w przypadku progresywnego wyszukiwania liniowego i binarnego - że tablica jest wstępnie posortowana - to zgodnie ze statystykami podanymi w linku możemy spodziewać się około 6-krotnego przyspieszenia dla IndexOf, przesunięcie jego złożoności między O (n 1 ÷ 6) a O (n 1 n 2 ), uśredniając do O (n 1 ceil (n 2 7 ÷ 12)) . Na koniec zwróć uwagę, że poniższe rozwiązanie nigdy nie będzie działać z obiektami, ponieważ obiektów w JavaScript nie można porównywać za pomocą wskaźników w JavaScript.
Zobacz mój drugi post , aby uzyskać więcej informacji na temat zastosowanego algorytmu wyszukiwania binarnego
Jeśli niepokoisz się rozmiarem pliku (co szanuję), możesz poświęcić trochę wydajności, aby znacznie zmniejszyć rozmiar pliku i zwiększyć łatwość konserwacji.
Aby udowodnić różnicę w szybkości, przyjrzyjmy się niektórym plikom JSPerf. W przypadku filtrowania tablicy 16 elementów , wyszukiwanie binarne jest około 17% szybsze niż indexOf, podczas gdy filterArrayByAnotherArray jest około 93% szybsze niż indexOf. W przypadku filtrowania tablicy składającej się z 256 elementów , wyszukiwanie binarne jest około 291% szybsze niż indexOf, podczas gdy filterArrayByAnotherArray jest około 353% szybsze niż indexOf. W przypadku filtrowania tablicy zawierającej 4096 elementów wyszukiwanie binarne jest około 2655% szybsze niż indexOf, podczas gdy filterArrayByAnotherArray jest około 4627% szybsze niż indexOf.
Odwrotne filtrowanie (jak bramka AND)
W poprzedniej sekcji podano kod, który pobierze tablicę A i tablicę B oraz usunie wszystkie elementy z A, które istnieją w B:
Ta następna sekcja zawiera kod do odwrotnego filtrowania, w którym usuwamy wszystkie elementy z A, które NIE istnieją w B. Ten proces jest funkcjonalnie równoważny zachowaniu tylko elementów wspólnych dla obu A i B, takich jak bramka AND:
Oto kod odwrotnego filtrowania:
Dla wolniejszej, mniejszej wersji kodu odwrotnego filtrowania, zobacz poniżej.
źródło
OA można również zaimplementować w ES6 w następujący sposób
ES6:
źródło
Najlepszym opisem
filter
funkcji jest https://developer.mozilla.org/pl/docs/Web/JavaScript/Referencje/Obiekty/Array/filterPowinieneś po prostu warunkować funkcję:
Nie możesz uzyskać dostępu do wartości zmiennej przed jej przypisaniem
źródło
Możesz skonfigurować funkcję filtru, aby iterowała po „tablicy filtrów”.
źródło
Możesz użyć filtru, a następnie dla funkcji filtrującej użyć redukcji tablicy filtrującej, która sprawdza i zwraca prawdę, gdy znajdzie dopasowanie, a następnie odwraca po powrocie (!). Funkcja filtrująca jest wywoływana raz na element tablicy. Nie wykonujesz porównania żadnego z elementów funkcji w swoim poście.
źródło
źródło
źródło
Bardziej elastyczna tablica filtrująca z innej tablicy, która zawiera właściwości obiektu
źródło
Możesz napisać ogólną funkcję filterByIndex () i skorzystać z wnioskowania o typie w TS, aby zaoszczędzić sobie kłopotów z funkcją wywołania zwrotnego:
powiedzmy, że masz swoją tablicę [1,2,3,4], którą chcesz przefiltrować () z indeksami określonymi w tablicy [2,4].
funkcja byIndex oczekuje funkcji elementu i tablicy i wygląda następująco:
wynik jest wtedy
źródło
Poniższe przykłady służą
new Set()
do tworzenia przefiltrowanej tablicy, która ma tylko unikalne elementy:Tablica z prymitywnymi typami danych: string, number, boolean, null, undefined, symbol:
Tablica z obiektami jako elementami:
źródło
Poniżej przykład
źródło
Rozwiązanie Jacka Giffina jest świetne, ale nie działa dla tablic z liczbami większymi niż 2 ^ 32. Poniżej znajduje się refaktoryzowana, szybka wersja filtrująca tablicę w oparciu o rozwiązanie Jacka, ale działa ona dla tablic 64-bitowych.
źródło