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.