NSComparisonResult选项

时间:2013-11-22 19:35:26

标签: ios uitableview uisearchbar

在我的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];
            }
        }
    }
}

恳请您教我如何进行搜索,任何字段的搜索字符串长度至少为三个字符。 谢谢。

2 个答案:

答案 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
    }]];
}