在我的iOS应用中,我实现了核心数据和搜索栏的表格视图。在当前状态下,搜索仅显示以搜索字符串开头的字段,但我想要的是显示包含至少三个字符长度的搜索文本的字段。
这是我的搜索功能代码:
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSLog(@"Previous Search Results were removed.");
[self.searchResults removeAllObjects];
for (Person *person in [self.fetchedResultsController fetchedObjects])
{
if ([scope isEqualToString:@"All"] || [person.firstname isEqualToString:scope])
{
NSComparisonResult result = [person.firstname compare:searchText
options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch)
range:NSMakeRange(0, [searchText length])];
if (result == NSOrderedSame)
{
NSLog(@"Adding person.firstname '%@' to searchResults as it begins with search text '%@'", person.firstname, searchText);
[self.searchResults addObject:person];
}
}
}
}
恳请您教我如何进行搜索,任何字段的搜索字符串长度至少为三个字符。 谢谢。
答案 0 :(得分:1)
至少开始讨论,天真的蛮力方法:
// get a set of all substrings; using a set means these will be deduplicated
NSMutableSet *substrings = [NSMutableSet set];
for(NSInteger index = 0; index < searchText.length - 3; index++)
[substrings addObject:[searchText substringWithRange:NSMakeRange(index, 3)]];
// search every person for every single last possibility
[self.searchResults removeAllObjects];
for(Person *person in [self.fetchedResultsController fetchedObjects])
{
// ... scope and whatever else tests here ...
for(NSString *string in substrings)
{
if([person.firstname rangeOfString:string].location != NSNotFound)
{
[self.searchResults addObject:person];
break; // exit the string in substrings loop early
}
}
}
答案 1 :(得分:1)
在我看来,最适合您要求的最简单方法是使用NSPredicate过滤掉[self.fetchedResultsController fetchedObjects]
数组并使用它。 NSPredicate可以应用于任何NSArray,以过滤其向该数组实例发送filteredArrayUsingPredicate:
消息的结果。所以我的建议是使用如下代码:
-(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope {
self.searchResults = [[self.fetchedResultsController fetchedObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
Person* person = evaluatedObject;
NSString* firstName = person.firstname;
//searchText having length < 3 should not be considered
if (!!searchText && [searchText length] < 3) {
return YES;
}
if ([scope isEqualToString:@"All"] || [firstName isEqualToString:scope]) {
return ([firstName rangeOfString:searchText].location != NSNotFound);
}
return NO; //if nothing matches
}]];
}