Mam tablicę docelową ["apple","banana","orange"]
i chcę sprawdzić, czy inne tablice zawierają jeden z elementów tablicy docelowej.
Na przykład:
["apple","grape"] //returns true;
["apple","banana","pineapple"] //returns true;
["grape", "pineapple"] //returns false;
Jak mogę to zrobić w JavaScript?
javascript
arrays
Alex
źródło
źródło
for
pętli i iteruj tablicę docelową. Jeśli każdy element jest zawarty w bieżącej tablicy (użyjcurrent.indexOf(elem) !== -1)
, to wszystkie są tam.Odpowiedzi:
Vanilla JS
ES2016:
ES6:
Jak to działa
some(..)
sprawdza każdy element tablicy względem funkcji testowej i zwraca true, jeśli jakikolwiek element tablicy przejdzie funkcję testową, w przeciwnym razie zwraca false.indexOf(..) >= 0
iincludes(..)
oba zwracają wartość true, jeśli podany argument jest obecny w tablicy.źródło
true
jeśli jakikolwiek element tablicy przejdzie przez funkcję testową. W przeciwnym razie zwracafalse
.[false, false, false]
zamiast pustej tablicy[]
?waniliowy js
źródło
some()
jest rad. Rezygnuje, gdy tylko coś pasuje.arr.some(v=> haystack.indexOf(v) >= 0)
arr.some(v => haystack.includes(v))
arr1.some(v => arr2.indexOf(v) >= 0)
.includes
, ponieważ najwyraźniej nie jest obsługiwany w IE: stackoverflow.com/questions/36574351/…Jeśli nie masz nic przeciwko używaniu libray, http://underscorejs.org/ ma metodę przecięcia, która może to uprościć:
Funkcja przecięcia zwróci nową tablicę z dopasowanymi elementami, a jeśli nie pasuje, zwróci pustą tablicę.
źródło
ES6 (najszybszy)
ES2016
Podkreślać
DEMO: https://jsfiddle.net/r257wuv5/
jsPerf: https://jsperf.com/array-contains-any-element-of-another-array
źródło
Jeśli nie potrzebujesz przymusu typu (z powodu użycia
indexOf
), możesz spróbować czegoś takiego:Gdzie
arr
zawiera elementy docelowe. Na koniecfound
pokaże, czy druga tablica miała co najmniej jedno dopasowanie do celu.Oczywiście możesz zamienić liczby na wszystko, czego chcesz użyć - ciągi znaków są w porządku, tak jak w twoim przykładzie.
W moim konkretnym przykładzie wynik powinien wynikać z
true
tego, że druga tablica3
istnieje w celu.AKTUALIZACJA:
Oto jak zorganizowałbym to w funkcję (z pewnymi drobnymi zmianami wcześniej):
DEMO: http://jsfiddle.net/u8Bzt/
W takim przypadku funkcję można zmodyfikować, aby
targetArray
została przekazana jako argument zamiast zakodowana na stałe w zamknięciu.AKTUALIZACJA 2:
Chociaż moje powyższe rozwiązanie może działać i być (mam nadzieję, że więcej) czytelne, uważam, że „lepszym” sposobem radzenia sobie z opisaną przeze mnie koncepcją jest zrobienie czegoś nieco inaczej. „Problem” z powyższym rozwiązaniem polega na tym, że
indexOf
wewnętrzna pętla powoduje całkowite zapętlenie tablicy docelowej dla każdego elementu w drugiej tablicy. Można to łatwo „naprawić” za pomocą „wyszukiwania” (mapa ... dosłownie obiekt JavaScript). Pozwala to na dwie proste pętle na każdą tablicę. Oto przykład:PRÓBNY: http://jsfiddle.net/5Lv9v/
Minusem tego rozwiązania jest to, że tylko liczby i ciągi (i logiczne) mogą być używane (poprawnie), ponieważ wartości są (domyślnie) konwertowane na ciągi i ustawiane jako klucze do mapy wyszukiwania. Nie jest to do końca dobre / możliwe / łatwe do wykonania dla wartości nieliteralnych.
źródło
undefined
... po to!!
jest” - to źle. Zwróci booleanską opozycję!
.Rozwiązanie ES6:
W przeciwieństwie do tego: Must zawiera wszystkie wartości.
Mam nadzieję, że będzie pomocna.
źródło
Możesz użyć lodash i zrobić:
Przecięcie zestawu odbywa się w obu kolekcjach, tworząc tablicę identycznych elementów.
źródło
intersection
będzie porównywać nawet po znalezieniu pierwszego dopasowania, aby znaleźć wszystkie. To jest jak używanie,filter
kiedy potrzebujeszfind
.Korzystanie z filtru / indeksu :
źródło
Lub możesz nawet uzyskać lepszą wydajność, jeśli najpierw dowiesz się, która z tych dwóch tablic jest dłuższa i robisz
Set
najdłuższą tablicę, stosującsome
metodę na najkrótszej:źródło
indexOf
iincludes
jesteś pierwszym, który odpowie z bardziej wydajne rozwiązania oparte na ustawionej przy użyciu natywnegoSet
, 4 lata po tym jak został wprowadzony do ECMAScript. +1Znalazłem tę krótką i słodką składnię pasującą do wszystkich lub niektórych elementów między dwiema tablicami. Na przykład
// LUB operacja. sprawdź, czy którykolwiek z elementów tablicy2 istnieje w tablicy1. Zwróci się, gdy tylko pojawi się pierwsze dopasowanie, ponieważ jakaś metoda psuje się, gdy funkcja zwraca PRAWDA
// drukuje PRAWDA
// ORAZ operacja. sprawdź, czy wszystkie elementy tablicy2 istnieją w tablicy1. Zwróci się, jak tylko nie będzie pierwszego dopasowania, ponieważ jakaś metoda psuje się, gdy funkcja zwraca PRAWDA
// drukuje FAŁSZ
Mam nadzieję, że pomoże komuś w przyszłości!
źródło
Możesz użyć zagnieżdżonego wywołania Array.prototype.some. Ma to tę zaletę, że zostanie zwolniony za kaucją przy pierwszym dopasowaniu zamiast innych rozwiązań, które będą przebiegać przez pełną zagnieżdżoną pętlę.
na przykład.
źródło
Oto interesujący przypadek, który powinienem podzielić.
Powiedzmy, że masz tablicę obiektów i tablicę wybranych filtrów.
Aby zastosować wybrane filtry do tej struktury, możemy
źródło
Napisałem 3 rozwiązania. Zasadniczo robią to samo. Powracają prawdziwe, gdy tylko się pojawią
true
. Napisałem 3 rozwiązania tylko dla pokazania 3 różnych sposobów robienia rzeczy. Teraz zależy to, co lubisz bardziej. Możesz użyć performance.now (), aby sprawdzić wydajność jednego lub drugiego rozwiązania. W moich rozwiązaniach sprawdzam również, która tablica jest największa, a która najmniejsza, aby zwiększyć wydajność operacji.Trzecie rozwiązanie może nie być najsłodsze, ale jest wydajne. Zdecydowałem się to dodać, ponieważ w niektórych wywiadach dotyczących kodowania nie wolno używać metod wbudowanych.
Wreszcie, pewnie ... możemy wymyślić rozwiązanie z 2 NESTED dla pętli (metoda brutalnej siły), ale chcesz tego uniknąć, ponieważ złożoność czasu jest zła O (n ^ 2) .
Uwaga:
indexOf () vs obejmuje ()
Który ma lepszą wydajność ?
indexOf()
trochę, ale zawiera, moim zdaniem, bardziej czytelny.Jeśli się nie mylę
.includes()
iindexOf()
używam pętli za sceną, będziesz przy O (n ^ 2) , używając ich z.some()
.UŻYWANIE pętli
KORZYSTANIE z .some ()
KORZYSTANIE Z MAPY Złożoność czasu O (2n) => O (n)
Kod w moim: stackblitz
Nie jestem ekspertem od wydajności ani BigO, więc jeśli coś, co powiedziałem, jest złe, daj mi znać.
źródło
Co powiesz na użycie kombinacji niektórych / findIndex i indexOf?
Więc coś takiego:
Aby uczynić go bardziej czytelnym, możesz dodać tę funkcjonalność do samego obiektu Array.
Uwaga: jeśli chcesz zrobić coś z predykatem, możesz zastąpić wewnętrzny indexOf innym findIndex i predykatem
źródło
Moje rozwiązanie stosuje pomocniki tablic Array.prototype.some () i Array.prototype.includes (), które również wykonują swoją pracę całkiem wydajnie
ES6
źródło
Jeszcze jedno rozwiązanie
Sprawdź, czy a1 zawiera cały element a2
źródło
Można to zrobić po prostu iterując po głównej tablicy i sprawdzając, czy inna tablica zawiera element docelowy, czy nie.
Spróbuj tego:
DEMO w JSFIDDLE
źródło
Z podkreślnikami
źródło
indexOf
, myślę wręcz przeciwnie :). Z drugiej strony zgadzam się nie dodawać bibliotek zewnętrznych, jeśli nie są one naprawdę potrzebne, ale nie mam obsesji na punkcie tego, biblioteki trzeciej części oferują nie tylko przydatne funkcje, ale także solidne funkcje. Na przykład: czy przetestowałeś już wszystkie przypadki i przeglądarki burmistrza ze swoim rozwiązaniem? (every
Dodanie do prototypu macierzy
Uwaga: Wielu zdecydowanie odradza to. Jedynym problemem, kiedy naprawdę byłby problem, było dodanie przez bibliotekę funkcji prototypu o tej samej nazwie (która zachowywała się inaczej) lub czegoś takiego.
Kod:
Bez użycia funkcji dużych strzałek:
Stosowanie
źródło
Waniliowy JS z częściowym dopasowaniem i bez rozróżniania wielkości liter
Problem z niektórymi wcześniejszymi podejściami polega na tym, że wymagają one dokładnego dopasowania każdego słowa . Ale co jeśli chcesz podać wyniki dla częściowych dopasowań?
Jest to przydatne, gdy chcesz podać pole wyszukiwania, w którym użytkownicy wpisują słowa, a wyniki mogą mieć te słowa w dowolnej kolejności, pozycji i wielkości.
źródło
Zaktualizuj odpowiedź @Paul Grimshaw, użyj
includes
insteedindexOf
dla bardziej czytelnegoźródło
Wymyśliłem rozwiązanie w węźle, używając podkreślenia js w następujący sposób:
źródło
Osobiście użyłbym następującej funkcji:
Metoda „toString ()” zawsze używa przecinków do oddzielenia wartości. Naprawdę będzie działać tylko z typami pierwotnymi.
źródło
Array .filter () z zagnieżdżonym wywołaniem do .find () zwróci wszystkie elementy w pierwszej tablicy, które są członkami drugiej tablicy. Sprawdź długość zwróconej tablicy, aby ustalić, czy któraś z drugiej tablicy znajdowała się w pierwszej tablicy.
źródło
źródło
źródło