Я создаю приложение iOS, и мне нужно выяснить, содержит ли NSString
любой из NSStrings
в NSArray
.
Как проверить, содержит ли NSString один из NSStrings в NSArray?
Ответ 1
BOOL found=NO;
for (NSString *s in arrayOfStrings)
{
if ([stringToSearchWithin rangeOfString:s].location != NSNotFound) {
found = YES;
break;
}
}
Ответ 2
Это может быть глупая оптимизация для вашего варианта использования, но в зависимости от того, насколько велик массив, который вы выполняете, может быть полезно/более эффективно использовать метод NSArray's
indexOfObjectWithOptions:passingTest:
.
С помощью этого метода вы передаете некоторые параметры и блок, содержащий ваш тест. Передача параметра NSEnumerationConcurrent
позволит оценить ваш блок на нескольких потоках одновременно и потенциально ускорить процесс. Я повторно использовал инвариантный тест, но несколько иначе. Блок функционально возвращает BOOL, подобный "найденной" переменной в инвариантной реализации. "* Stop = YES;" строка указывает, что итерация должна прекратиться.
Дополнительную информацию см. в справочной документации NSArray. Reference
NSArray *arrayOfStrings = ...;
NSString *stringToSearchWithin = ...";
NSUInteger index = [arrayOfStrings indexOfObjectWithOptions:NSEnumerationConcurrent
passingTest:^(id obj, NSUInteger idx, BOOL *stop)
{
NSString *s = (NSString *)obj;
if ([stringToSearchWithin rangeOfString:s].location != NSNotFound) {
*stop = YES;
return YES;
}
return NO;
}];
if (arrayOfStrings == nil || index == NSNotFound)
{
NSLog(@"The string does not contain any of the strings from the arrayOfStrings");
return;
}
NSLog(@"The string contains '%@' from the arrayOfStrings", [arrayOfStrings objectAtIndex:index]);
Ответ 3
Очень небольшое улучшение безопасности в ответ Адама: есть большая проблема с "objectAtIndex:", потому что она полностью не потокобезопасна и слишком часто приводит к сбою вашего приложения. Поэтому я:
NSArray *arrayOfStrings = ...;
NSString *stringToSearchWithin = ...";
__block NSString *result = nil;
[arrayOfStrings indexOfObjectWithOptions:NSEnumerationConcurrent
passingTest:^(NSString *obj, NSUInteger idx, BOOL *stop)
{
if ([stringToSearchWithin rangeOfString:obj].location != NSNotFound)
{
result = obj;
*stop = YES;
//return YES;
}
return NO;
}];
if (!result)
NSLog(@"The string does not contain any of the strings from the arrayOfStrings");
else
NSLog(@"The string contains '%@' from the arrayOfStrings", result);
Ответ 4
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF IN %@", theArray];
BOOL result = [predicate evaluateWithObject:theString];
Ответ 5
Как и в случае с выпуском iOS8, Apple добавила новый метод NSString
, называемый localizedCaseInsensitiveContainsString
. Это точно сделает то, что вам нужно, проще:
BOOL found = NO;
NSString *string = @"ToSearchFor";
for (NSString *s in arrayOfStrings){
if ([string localizedCaseInsensitiveContainsString:s]) {
found = YES;
break;
}
}