JavaScript: indexOf vs. Match podczas wyszukiwania ciągów?
Pomijając czytelność, czy istnieją jakieś dostrzegalne różnice (być może wydajność) między używaniem
str.indexOf("src")
I
str.match(/src/)
Ja osobiście wolę match
(i regexp), ale koledzy zdają się iść w drugą stronę. Zastanawialiśmy się, czy to ma znaczenie ...?
EDIT:
Powinienem powiedzieć na początku, że jest to dla funkcji, które będą wykonywać częściowe dopasowanie zwykłego ciągu znaków (aby odebrać identyfikatory w atrybutach klasy dla JQuery), a nie Pełne wyszukiwanie regexp z dzikimi kartami itp.
class='redBorder DisablesGuiClass-2345-2d73-83hf-8293'
Więc jest różnica między:
string.indexOf('DisablesGuiClass-');
I
string.match(/DisablesGuiClass-/)
9 answers
RegExp jest rzeczywiście wolniejszy niż indexOf (możesz go zobaczyć tutaj), chociaż normalnie nie powinno to być problemem. Z RegExp, musisz również upewnić się, że ciąg znaków jest poprawnie unikalny, co jest dodatkową rzeczą do przemyślenia.
Obie te kwestie na bok, jeśli dwa narzędzia robią dokładnie to, czego potrzebujesz, dlaczego nie wybrać prostszego?
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-21 10:06:58
Twoje porównanie może nie być do końca uczciwe. indexOf
jest używany z prostymi łańcuchami i dlatego jest bardzo szybki; match
przyjmuje Wyrażenie regularne - oczywiście może być wolniejsze w porównaniu, ale jeśli chcesz dopasować regex, nie zajdziesz daleko z indexOf
. Z drugiej strony, silniki wyrażeń regularnych mogą być zoptymalizowane i poprawiają wydajność w ostatnich latach.
W Twoim przypadku, gdzie szukasz ciągu słownego, indexOf
powinno wystarczyć. Jest jeszcze jeden aplikacja dla wyrażeń regularnych: jeśli chcesz dopasować całe słowa i chcesz uniknąć dopasowania podciągów, wtedy wyrażenia regularne dają Ci "kotwice graniczne słowa". Na przykład:
indexOf('bar')
Znajdzie bar
trzy razy w bar, fubar, barmy
, natomiast
match(/\bbar\b/)
Będzie pasować bar
tylko wtedy, gdy nie jest częścią dłuższego słowa.
Jak widać w komentarzach, dokonano pewnych porównań, które pokazują, że regex może być szybszy niż indexOf
- jeśli ma kluczowe znaczenie dla wydajności, możesz może być konieczne profilowanie kodu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-29 07:46:42
Tutaj wszystkie możliwe sposoby (względnie) wyszukiwania ciągu
// 1. includes (introduced in ES6)
var string = "string to search for substring",
substring = "sea";
string.includes(substring);
// 2. sznurek.indexOf
var string = "string to search for substring",
substring = "sea";
string.indexOf(substring) !== -1;
// 3. RegExp: test
var string = "string to search for substring",
expr = /sea/; // no quotes here
expr.test(string);
// 4. sznurek.match
var string = "string to search for substring",
expr = "/sea/";
string.match(expr);
//5. sznurek.Szukaj
var string = "string to search for substring",
expr = "/sea/";
string.search(expr);
Benchmarki wydają się być skręcone specjalnie dla ES6 includes, przeczytaj komentarze.
W CV:
Jeśli nie potrzebujesz zapałek. = > Albo potrzebujesz regex i dlatego użyj test. W przeciwnym razie es6 zawiera lub indexOf. Wciąż test vs indeks są blisko.I dla includes vs indexOf:
Wydają się być takie same: https://jsperf.com/array-indexof-vs-includes/4 (gdyby było inaczej to byłoby dziwne, w większości wykonują to samo z wyjątkiem różnic, które expose check this )
I dla mojego własnego testu porównawczego. tutaj jest http://jsben.ch/fFnA0 Możesz go przetestować (zależy od przeglądarki) [testuj wielokrotnie] tutaj Jak to wykonało (wiele uruchomień indexOf i zawiera jeden beat drugi, i są one blisko). Więc są takie same. [tutaj przy użyciu tej samej platformy testowej, co artykuł powyżej].
I tutaj dla długiej wersji tekstu (8 razy dłużej) http://jsben.ch/wSBA2
Testowałem chrome i Firefoksa, to samo.
Zawiadomienie jsben.ch nie obsługuje przepełnienia pamięci (lub nie ma ograniczeń poprawnie. Nie pokazuje żadnej wiadomości) więc wynik może się pomylić, jeśli dodasz więcej niż 8 duplikacji tekstu (8 działa dobrze). Ale wniosek jest taki, że dla bardzo dużego tekstu wszystkie trzy działają w ten sam sposób. W przeciwnym razie dla krótkiego indexOf i includes są takie same i testują trochę wolniej. lub może być taka sama jak się wydawało w chrome (firefox 60 jest wolniejszy).
Zawiadomienie z jsben.ch: nie świruj, jeśli uzyskasz niespójny wynik. Spróbuj o innej porze i sprawdź, czy jest spójna, czy nie. Zmień przeglądarkę, czasami po prostu działają całkowicie źle. Błąd lub złe obchodzenie się z pamięcią. Czy coś.
Ex:
Tutaj też mój benchmark na jsperf (lepsze szczegóły i obsługa wykresów dla wielu przeglądarek)
(góra jest chromowana)
Normal tekst
https://jsperf.com/indexof-vs-includes-vs-test-2019
resume: includes i indexOf mają taką samą perefrmancję. testuj wolniej.
(wszystkie trzy wykonują to samo w chromie)
Długi tekst (12 razy dłuższy niż normalny)
https://jsperf.com/indexof-vs-includes-vs-test-2019-long-text-str/
resume: wszystkie trzy wykonują to samo. (chrom i firefox)
Bardzo krótki sznurek
https://jsperf.com/indexof-vs-includes-vs-test-2019-too-short-string/
resume: includes i indexOf wykonują to samo i testują wolniej.
Uwaga: o benchmarku powyżej. W wersji Bardzo krótki ciąg (jsperf) miał duży błąd dla chrome. Widzieć moimi oczami. około 60 prób przeprowadzono dla obu indexOf i zawiera w ten sam sposób (powtórzył wiele czas). I testować trochę mniej i tak wolniej. nie daj się zwieść z niewłaściwym wykresem. To oczywiste. Ta sama praca testowa ok dla Firefoksa, na pewno jest to błąd.
Tutaj ilustracja: (pierwszy obrazek był testem na Firefoksie) waaaa. Nagle indexOf stał się Supermanem. Ale jak powiedziałem, zrobiłem test, i spojrzał na liczbę próbek było około 60. Zarówno indexOf jak i includes wykonali to samo. Błąd na jspref . Oprócz tego (może dlatego, że problem związany z ograniczeniem pamięci) cała reszta była spójna, podaje więcej szczegółów. I widzisz, jak wiele prostych dzieje się w czasie rzeczywistym.
Ostatnie wznowienie
IndexOf vs includes = > Same performance
Test = > Może być wolniejszy dla krótkich łańcuchów lub tekstu. I to samo w przypadku długich tekstów. I to ma sens dla napowietrznych, które dodaje silnik regex. W chrome wydawało się, że to nie ma znaczenia.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-05 16:32:49
Jeśli próbujesz wyszukać podcięcia niezależnie od wielkości liter, match
wydaje się być szybsze niż kombinacja indexOf
i toLowerCase()
Sprawdź tutaj - http://jsperf.com/regexp-vs-indexof/152
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-07 12:54:13
Pytasz, czy str.indexOf('target')
lub str.match(/target/)
powinny być preferowane. Jak sugerowały inne plakaty, przypadki użycia i typy zwrotów tych metod są różne. Pierwszy pyta " gdzie w str
mogę najpierw znaleźć 'target'
?"Drugie pytanie" czy str
pasuje do wyrażenia regularnego, a jeśli tak, to jakie są wszystkie dopasowania dla powiązanych grup przechwytywania?"
Problem polega na tym, że żaden z nich technicznie nie jest przeznaczony do zadawania prostszego pytania " czy łańcuch zawiera podłańcuch?"Jest coś, co jest wprost zaprojektowane do tego:
var doesStringContainTarget = /target/.test(str);
Istnieje kilka zalet korzystania z regex.test(string)
:
- Zwraca wartość logiczną, na której ci zależy
- jest bardziej wydajny niż
str.match(/target/)
(i rywalestr.indexOf('target')
) - Jeśli z jakiegoś powodu
str
jestundefined
lubnull
, otrzymaszfalse
(pożądany wynik) zamiast rzucaćTypeError
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-06 18:16:13
Użycie indexOf
powinno teoretycznie być szybsze niż wyrażenie regularne, gdy szukasz zwykłego tekstu, ale powinieneś zrobić kilka porównawczych benchmarków samodzielnie, jeśli martwisz się o wydajność.
Jeśli wolisz match
i jest wystarczająco szybki dla Twoich potrzeb, to idź na to.
Jeśli to coś warte, zgadzam się z twoimi kolegami w tej sprawie: użyłbym indexOf
podczas wyszukiwania zwykłego ciągu, A używać match
itp tylko wtedy, gdy potrzebuję dodatkowej funkcjonalności zapewnianej przez zwykłe wyrażenia.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-21 10:02:44
Sprawność indexOf
będzie co najmniej nieco szybsza niż match
. Wszystko sprowadza się do konkretnego wdrożenia. Decydując się na użycie zadaj sobie następujące pytanie:
Czy wystarczy indeks integer czy potrzebujesz funkcjonalności wyrażenia regularnego wynik meczu?
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-21 10:05:21
Wartości zwracane są różne
Oprócz implikacji wydajności, które są rozwiązywane przez inne odpowiedzi, ważne jest, aby zauważyć, że wartości zwracane dla każdej metody są różne; więc metody nie mogą być jedynie zastępowane bez zmiany logiki.
Return value of .indexOf
: integer
Indeks wewnątrz obiektu wywołującego
String
pierwszego wystąpienia określonej wartości, rozpoczynającego wyszukiwanie wfromIndex
.
zwraca-1
Jeśli wartość nie została znaleziona.
Return value of .match
: array
Tablica zawierająca cały wynik meczu i wszelkie nawiasy-przechwycone dopasowane wyniki.
zwracanull
jeśli nie było dopasowania .
Ponieważ .indexOf
zwraca 0
jeśli łańcuch wywołujący zaczyna się z podaną wartością, prosty test prawdziwości nie powiedzie się.
Na przykład:
biorąc pod uwagę tę klasę ...
class='DisablesGuiClass-2345-2d73-83hf-8293 redBorder'
...wartości zwracane dla każdego będą się różnić:
// returns `0`, evaluates to `false`
if (string.indexOf('DisablesGuiClass-')) {
… // this block is skipped.
}
vs.
// returns `["DisablesGuiClass-"]`, evaluates to `true`
if (string.match(/DisablesGuiClass-/)) {
… // this block is run.
}
Prawidłowym sposobem przeprowadzenia testu z powrotem z .indexOf
jest sprawdzenie z -1
:
if (string.indexOf('DisablesGuiClass-') !== -1) {
// ^returns `0` ^evaluates to `true`
… // this block is run.
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55
Pamiętaj Internet Explorer 8 nie rozumie indexOf
.
Ale jeśli nikt z Twoich użytkowników nie korzysta z ie8 (Google analytics powie Ci), pomiń tę odpowiedź.
możliwe rozwiązanie do naprawy ie8:
Jak naprawić Array indexOf () w JavaScript dla przeglądarek Internet Explorer
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:03:05