检查String是否包含数组中的任何String

我知道我可以检查一个字符串是否包含这样的另一个字符串

NSString *string = @"hello bla bla"; if ([string rangeOfString:@"bla"].location == NSNotFound) { NSLog(@"string does not contain bla"); } else { NSLog(@"string contains bla!"); } 

但是,如果我有一个NSArray *arary = @[@"one",@"two", @"three", @"four"] ,我想检查一个字符串是否包含其中一个而不仅仅是循环或者有一堆或( || )。 所以它会是这样的

 if (array contains one or two or three or four) { //do something } 

但是,如果我有一个更长的arrays,这变得乏味,所以有另一种方式,而不只是循环?

编辑

我想检查myArray是否在valuesArray中具有任何这些值

 valuesArray =@[@"one",@"two", @"three", @"four"]; myArray = [@"I have one head", @"I have two feet", @"I have five fingers"] 

OUTPUT

 outputArray = @[@"I have one head", @"I have two feet"] 

你去:

 NSArray* arrRet = [myArray filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id __nonnull evaluatedObject, NSDictionary * __nullable bindings) { for(NSString* val in valuesArray) { if ([evaluatedObject rangeOfString:val].location != NSNotFound) return true; } return false; }]]; 

arrRet包含两个所需的字符串。

稍微有点魔力,你可以在不编写循环的情况下获得代码:P

 NSArray* arrRet = [myArray filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary * bindings) { BOOL __block match = false; [valuesArray enumerateObjectsUsingBlock:^(id __nonnull obj, NSUInteger idx, BOOL * __nonnull stop) { *stop = match = [evaluatedObject rangeOfString:obj].location != NSNotFound; }]; return match; }]]; 

您可以使用NSCompoundPredicate

 NSCompoundPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:subPredicates]; 

您的subPredicates必须在哪里

 ( SELF CONTAINS[c] "one", SELF CONTAINS[c] "two", SELF CONTAINS[c] "three", SELF CONTAINS[c] "four" ) 

来自那里

 NSArray *array = @[@"one", @"two", @"three", @"four"] 

你可以使用for循环,但是当你反对时,让我们作弊:

通过使用类别I每个NSArrayfunction映射,但我使用枚举而不是循环

 @interface NSArray (Map) -(NSArray *) vs_map:(id(^)(id obj))mapper; @end @implementation NSArray (Map) -(NSArray *)vs_map:(id (^)(id))mapper { NSMutableArray *mArray = [@[] mutableCopy]; [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { id mapped = mapper(obj); [mArray addObject:mapped]; }]; return [mArray copy]; } @end 

现在我可以创建subPredicates了

 NSArray *subPredicates = [arary vs_map:^id(NSString *obj) { return [NSPredicate predicateWithFormat:@"SELF contains[c] %@", obj]; }]; 

并创建复合谓词

 NSCompoundPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:subPredicates]; 

并使用它

 BOOL doesContain = [predicate evaluateWithObject:string]; 

etvoilà:没有(明显的)循环,虽然有一个隐藏在枚举中,也可能在谓词中。


现在有了改变的问题,你基本上要求过滤。 您可以使用相同的谓词:

 NSArray *testarray = @[@"I have one head", @"I have two feet", @"I have five fingers"]; NSArray *arary = @[@"one",@"two", @"three", @"four"]; NSArray *subPredicates = [arary vs_map:^id(NSString *obj) { return [NSPredicate predicateWithFormat:@"SELF contains[c] %@", obj]; }]; NSCompoundPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:subPredicates]; NSArray *results = [testarray filteredArrayUsingPredicate:predicate]; 

results现在包含

 ( I have one head, I have two feet ) 

完整的代码

 #import  @interface NSArray (Map) -(NSArray *) vs_map:(id(^)(id obj))mapper; @end @implementation NSArray (Map) -(NSArray *)vs_map:(id (^)(id))mapper { NSMutableArray *mArray = [@[] mutableCopy]; [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { id mapped = mapper(obj); [mArray addObject:mapped]; }]; return [mArray copy]; } @end int main(int argc, const char * argv[]) { @autoreleasepool { NSArray *testarray = @[@"I have one head", @"I have two feet", @"I have five fingers"]; NSArray *arary = @[@"one",@"two", @"three", @"four"]; NSArray *subPredicates = [arary vs_map:^id(NSString *obj) { return [NSPredicate predicateWithFormat:@"SELF contains[c] %@", obj]; }]; NSCompoundPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:subPredicates]; NSArray *results = [testarray filteredArrayUsingPredicate:predicate]; } return 0; } 

除了我欺骗我的另一个问题,这里有一个想法,如何真正避免时间昂贵的循环:使用集计算魔术!

  • 创建了一个类’Sentence’,用要测试的字符串实例化它
  • 创建了一个“Word”类,用于搜索单词
  • 覆盖两个类’ isEqual:方法,以匹配句子中是否有一个单词(也使用那里设置!)
  • 把它们放到一个数组中。
  • 从这个数组创建一个NS(*)Set对象
  • 将所有单词放在一组中
  • 执行联合就可以了。