Porównanie bez rozróżniania wielkości liter NSString


Odpowiedzi:


564
if( [@"Some String" caseInsensitiveCompare:@"some string"] == NSOrderedSame ) {
  // strings are equal except for possibly case
}

Dokumentacja znajduje się w Metodach wyszukiwania i porównywania


152
Warto wspomnieć, że w przypadku, gdy @"Some String"zostanie odebrane z innego połączenia i tak się stanie nil, ifpodasz truejako, że wysłanie caseInsensitiveComparena niljest ważne i skutkuje innym, nilktóry w naszym przypadku w porównaniu z NSOrderedSamepowróci true( NSOrderedSamejest zdefiniowany jako 0). Może to być źródłem dość niszczycielskich błędów, tak jak w moim przypadku. Twoje zdrowie!
matm

10
Moim obejściem tego problemu jest wdrożenie tego porównania jako metody wewnątrz kategorii, NSStringktóra zwraca wartość logiczną. Następnie, jeśli ciąg otrzymujący jest nil, metoda jako całość zwraca NO.
Defragged

50
 NSString *stringA;
 NSString *stringB;

 if (stringA && [stringA caseInsensitiveCompare:stringB] == NSOrderedSame) {
     // match
 }

Uwaga: stringA && wymagane jest, bo gdy stringAjest nil:

 stringA = nil;
 [stringA caseInsensitiveCompare:stringB] // return 0

i tak się dzieje NSOrderedSamejest również zdefiniowany jako 0.

Poniższy przykład to typowa pułapka:

 NSString *rank = [[NSUserDefaults standardUserDefaults] stringForKey:@"Rank"];
 if ([rank caseInsensitiveCompare:@"MANAGER"] == NSOrderedSame) {
     // what happens if "Rank" is not found in standardUserDefaults
 }

46

Alternatywą, jeśli chcesz mieć większą kontrolę niż tylko rozróżnianie wielkości liter, jest:

[someString compare:otherString options:NSCaseInsensitiveSearch];

Wyszukiwanie numeryczne i niewrażliwość na znaki diakrytyczne to dwie przydatne opcje.


4
Jak zauważono powyżej przez matm, to zwróci true, jeśli someString ma wartość zero.
nh32rg

@ nh32rg Czy możesz po prostu nadrobić fałszywy wynik pozytywny, zmieniając wyrażenie if na coś podobnegoif ([someString compare:otherString options:NSCaseInsensitiveSearch] && someString.length > 0 && someString != (id)[NSNull null])
KingPolygon

1
właściwie musisz napisać [... comapre: ...] == 0, ponieważ porównaj return NSOrderSame (= 0), jeśli dwa ciągi są takie same. for, someString! = (id) [NSNull null], nie sądzę, że jest to wymagane, ponieważ jeśli null, to długość wynosi zero. Zwykle porównuję w ten sposób: if (someString.length> 0 && [someString porównaj: ortherString opcje: NSCaseIntensitiveSearch] == 0)
Tran Quan

23

Zawsze możesz upewnić się, że są w tym samym przypadku przed porównaniem:

if ([[stringX uppercaseString] isEqualToString:[stringY uppercaseString]]) {
    // They're equal
}

Główną korzyścią jest unikanie potencjalnego problemu opisanego przez matm dotyczącego porównywania ciągów zerowych. Możesz albo sprawdzić, czy łańcuch nie jest zerowy przed wykonaniem jednej z compare:options:metod, albo możesz być leniwy (jak ja) i zignorować dodatkowy koszt tworzenia nowego łańcucha dla każdego porównania (co jest minimalne, jeśli robisz tylko jedną lub dwa porównania).


3
Manipulowanie obudową do porównywania zwykle nie jest mądrym posunięciem (np. Test indyka: moserware.com/2008/02/does-your-code-pass-turkey-test.html ). Jeśli masz porównanie wielkości liter obsługiwane przez język (np. caseInsensitiveCompare), Zawsze używaj tego.
Ohad Schneider,

7
- (NSComparisonResult)caseInsensitiveCompare:(NSString *)aString

12
Jest to o wiele bardziej przydatne dla ludzi, jeśli odpowiedzi mają jakiś kontekst i opis.
jowie

7

Nowy sposób na zrobienie tego. iOS 8

let string: NSString = "Café"
let substring: NSString = "É"

string.localizedCaseInsensitiveContainsString(substring) // true

wersja objC: if (string && [string localizedCaseInsensitiveContainsString: substring])
ski_squaw

OP prosi o „porównanie bez rozróżniania wielkości liter” . Jeśli twoje rozwiązanie zwraca true„Café” i „É”, to zdecydowanie NIE jest poprawna odpowiedź.
Alexander Abakumov

6

Wypróbuj tę metodę

- (NSComparisonResult)caseInsensitiveCompare:(NSString *)aString

6

Konwersja odpowiedzi Jasona Coco na Swift dla głęboko leniwych :)

if ("Some String" .caseInsensitiveCompare("some string") == .OrderedSame)
{
  // Strings are equal.
}

1
jest potrzebny dla tych, których XCodes odmawiają autouzupełniania! : D
Nitin Alabur

5

aby sprawdzić z prefiksem jak w iPhone ContactApp

([string rangeOfString:prefixString options:NSCaseInsensitiveSearch].location == 0)

ten blog był dla mnie przydatny


1

Alternatywne rozwiązanie dla szybkiego:

Aby zrobić zarówno UpperCase:

na przykład:

if ("ABcd".uppercased() == "abcD".uppercased()){
}

lub zrobić zarówno LowerCase:

na przykład:

if ("ABcd".lowercased() == "abcD".lowercased()){
}

0

Na macOS możesz po prostu użyć -[NSString isCaseInsensitiveLike:], który zwraca BOOLtak jak -isEqual:.

if ([@"Test" isCaseInsensitiveLike: @"test"])
    // Success

-3
NSMutableArray *arrSearchData;  
NSArray *data=[arrNearByData objectAtIndex:i];
NSString *strValue=[NSString stringWithFormat:@"%@", [data valueForKey:@"restName"]];
NSRange r = [strValue rangeOfString:key options:NSCaseInsensitiveSearch];

if(r.location != NSNotFound)
{
     [arrSearchData addObject:data];
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.