2014-11-12 21 views
6

Przechodzę przegląd kodu i jestem ciekawy, czy lepiej jest przekonwertować ciągi znaków na wielkie lub małe litery w JavaScript podczas próby porównania ich podczas ignorowania wielkości liter.Czy lepiej jest porównywać ciągi przy użyciu doLowerCase lub toUpperCase w JavaScript?

Trivial przykład:

var firstString = "I might be A different CASE"; 
var secondString = "i might be a different case"; 
var areStringsEqual = firstString.toLowerCase() === secondString.toLowerCase(); 

czy mam to zrobić:

var firstString = "I might be A different CASE"; 
var secondString = "i might be a different case"; 
var areStringsEqual = firstString.toUpperCase() === secondString.toUpperCase(); 

Wydaje się, że zarówno „powinien” lub będzie działać przy ograniczonych zestawów znaków jak tylko angielskich liter, więc jeden więcej krzepki od drugiego?

Jako notatkę, MSDN zaleca normalizacji sznurki na wielkie litery, ale to dla kodu zarządzanego (prawdopodobnie C# & F #, ale mają fantazyjne StringComparers i bibliotek podstawką) http://msdn.microsoft.com/en-us/library/bb386042.aspx

+0

Ponieważ większość ciągów będzie zawierała więcej małych liter, przynajmniej konwersja na małe litery będzie zawierała mniej znaków, ale inne niż to. Czy jest jakaś różnica? –

+1

Nie jestem pewien, czy istnieje jakakolwiek inna różnica w JavaScript, link MSDN mówi, że istnieją pewne znaki, które nie mogą wykonać podróży w obie strony - "Ciągi powinny być znormalizowane do wielkich liter. Mała grupa znaków, gdy są konwertowane na małe litery, nie może odbyć podróży w obie strony. Aby zrobić podróż w obie strony, należy przekonwertować znaki z jednego ustawienia narodowego na inne, które reprezentuje dane postaci w inny sposób, a następnie dokładnie odczytać oryginalne znaki ze skonwertowanych znaków. " - Ale nie jestem pewien, czy jest to unikalne dla .Net, czy też dotyczy wszystkich/większości języków programowania. –

+1

Zgaduję, że zależy to od przeglądarki, jak te dwie metody działają wewnętrznie, ale prawdopodobnie oba iterują po znakach i sprawdzają i konwertują je, więc nie ma to znaczenia. W prawdziwym życiu na pewno nie ma to znaczenia. – adeneo

Odpowiedz

9

Poprawiona odpowiedź

Minęło sporo czasu, gdy odpowiedziałem na to pytanie. Podczas gdy kwestie kulturowe nadal są prawdziwe (i nie sądzę, że kiedykolwiek odejdą), opracowanie standardu ECMA-402 spowodowało, że moja pierwotna odpowiedź ... była przestarzała (lub przestarzała?).

Najlepszym rozwiązaniem dla porównywania ciągów tekstów wydaje się być za pomocą funkcji toLocaleCompare() z odpowiednich lokalizacjach i opcji:

var locale = 'en'; // that should be somehow detected and passed on to JS 
var firstString = "I might be A different CASE"; 
var secondString = "i might be a different case"; 
if (firstString.localeCompare(secondString, locale, {sensitivity: 'accent'}) === 0) { 
    // do something when equal 
} 

Pozwoli to porównać dwa ciągi liter wielkość liter, ale akcent wrażliwych (na przykład a =).
Jeśli to nie wystarczy, ze względu na wydajność, może chcesz użyć toLocaleUpperCase() lub toLocaleLowerCase() przekazując jako parametr locale:

if (firstString.toLocaleUpperCase(locale) === secondString.toLocaleUpperCase(locale)) { 
    // do something when equal 
} 

Teoretycznie nie powinno być żadnych różnic. W praktyce, subtelnych szczegółów realizacji (lub braku realizacji w danej przeglądarce) mogą przynieść inne wyniki ...

Original odpowiedzi

Nie jestem pewien, czy naprawdę ma na to pytanie w Internationalization (i18n) tag, ale odkąd ...
Prawdopodobnie najbardziej nieoczekiwana odpowiedź to: ani.

Istnieje tons of problems z konwersją przypadku, co nieuchronnie prowadzi do problemów funkcjonalnych, jeśli chcesz przekonwertować skrzynkę znaków bez wskazywania języka (jak w przypadku JavaScript). Na przykład:

  1. Istnieje wiele języków naturalnych, które nie mają pojęcia wielkich i małych liter. Nie ma sensu próbować ich konwertować (chociaż to zadziała).
  2. Istnieją reguły specyficzne dla języka do konwersji ciągu. Niemiecki znak sharp S (ß) zostanie przekonwertowany na dwie wielkie litery S (SS).
  3. Turecki i Azerbejdżański (lub Azerski, jeśli wolisz) ma "bardzo dziwny" concept of two i characters: bez kropek ı (który konwertuje na wielkie litery I) i kropkowany i (który zamienia na wielkie litery İ < - ta czcionka nie pozwala na poprawną prezentację, ale to jest naprawdę inny glif).
  4. Język grecki ma wiele "dziwnych" reguł konwersji. Jedna szczególna reguła dotyczy wielkiej litery sigma (Σ), która w zależności od miejsca w słowie ma dwa małe odpowiedniki: sigma (σ) i sigma (ς). Istnieją również inne reguły konwersji w odniesieniu do znaków "akcentowanych", ale są one często pomijane podczas implementacji funkcji konwersji.
  5. Niektóre języki has title-case letters, tj. LJ, które należy przekształcić w rzeczy typu LJ lub mniej odpowiednio LJ. To samo dotyczy ligatures.
  6. W końcu istnieje wiele compatibility characters, które mogą oznaczać to samo, co próbujesz porównać, ale składają się z zupełnie innych postaci. Aby to pogorszyć, rzeczy takie jak "ae" mogą być odpowiednikiem "ä" w języku niemieckim i fińskim, ale odpowiednik "æ" w języku duńskim.

Próbuję Cię przekonać, że naprawdę lepiej jest porównać dane wprowadzane przez użytkownika, zamiast je konwertować. Jeśli nie jest to związane z użytkownikiem, prawdopodobnie nie ma to znaczenia, ale konwersja przypadku będzie zawsze wymagać czasu. Po co się męczyć?

1

To nie zależy od przeglądarki, tak jak to jest tylko zaangażowany javascript. zarówno dadzą wydajności w oparciu o brak znaków muszą być zmienione (przypadek przerzucanie)

var areStringsEqual = firstString.toLowerCase() === secondString.toLowerCase(); 
var areStringsEqual = firstString.toUpperCase() === secondString.toUpperCase(); 

Jeśli używasz testu przygotowanego przez @adeneo można poczuć to przeglądarka zależny, ale zrobić kilka innych wejść testowych, takich jak " AAAAAAAAAAAAAAAAAAAAAAA "&" aaaaaaaaaaaaaaaaaaaaaaaaa "i porównaj.

Wydajność Javascript zależy od przeglądarki, jeśli istnieje jakaś dom api lub jakakolwiek domowa manipulacja/interakcja, w przeciwnym razie dla wszystkich zwykłych javascript będzie ona zapewniała taką samą wydajność.