How to search(Predicate) content from list like Xcode suggestion?

若如初见. 提交于 2020-01-10 04:44:05

问题


I think everyone notice XCode suggestions list. Check this screenshot

As per Apple document doesn't provide what expected ouptut.

NSPredicate *inPredicate = [NSPredicate predicateWithFormat: @"attribute CONTAINS[cd] %@", aCollection];

Provide continuous search text only.

Is this possible, How to search content like this?


回答1:


A possible solution, is to use a Regular Expression for that. We just need to insert .* between each letter (and before and after the string) which means "any character (except for line terminators)". It seems that's what's used for the search on XCode completion.

NSMutableArray *letters = [[NSMutableArray alloc] init];
[searchString enumerateSubstringsInRange:NSMakeRange(0, [searchString length])
                                 options:NSStringEnumerationByComposedCharacterSequences
                              usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
    [letters addObject:substring];
}];
NSMutableString *pattern = [[NSMutableString alloc] initWithString:@".*"];
[pattern appendString:[letters componentsJoinedByString:@".*"]];
[pattern appendString:@".*"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.%K MATCHES[C] %@", keyToFilter, pattern];

Sample to play, insert just before:

NSString *keyToFilter = @"attribute";
NSArray *array = @[@{keyToFilter:@"UITextField"}, @{keyToFilter:@"nsarray"}, @{keyToFilter:@"uitf"}];
NSString *searchString = @"uitf";

and just after:

NSArray *filtered = [array filteredArrayUsingPredicate:predicate];
NSLog(@"SearchString: %@\nFiltered: %@", searchString, ([filtered count]?[filtered valueForKey:keyToFilter]:@"NO RESULT"));

Output:

$>SearchString: uitf
Filtered: (
    UITextField,
    uitf
)

The code taken for construction the array of letters is from here. Different solutions could have been used to create pattern, it's maybe not the best one, but it's a working one.

Bonus:

And for fun (I was intriguing on how doing it), a possible way to color the list (I made an array of NSAttributedString) to adapt (not fully tested or errors free):

NSMutableArray *filteredColored = [[NSMutableArray alloc] init];
for (NSDictionary *aDict in filtered) //or for (MyObjectClass *myObject in filtered)
{
    NSString *aFilteredValue = aDict[keyToFilter]; //or NSString *aFilteredValue = [myObject attribute]
    NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] initWithString:aFilteredValue attributes:@{}];
    NSInteger currentIndex = 0;
    for (NSString *aLetter in letters)
    {
        NSRange rangeFound = [aFilteredValue rangeOfString:aLetter
                                                   options:NSCaseInsensitiveSearch
                                                     range:NSMakeRange(currentIndex, [aFilteredValue length]-currentIndex)];
        if (rangeFound.location != NSNotFound)
        {
            currentIndex = rangeFound.location+rangeFound.length;
            [attr addAttribute:NSBackgroundColorAttributeName value:[UIColor yellowColor] range:rangeFound];
        }
    }
    [filteredColored addObject:attr];
}


来源:https://stackoverflow.com/questions/44412710/how-to-searchpredicate-content-from-list-like-xcode-suggestion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!