如何从Xcode建议的列表中搜索(谓词)内容?

时间:2017-06-07 12:31:50

标签: ios xcode nspredicate search-suggestion

我想大家都会注意到XCode的建议清单。查看此屏幕截图

enter image description here

As per Apple document doesn't provide what expected ouptut

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

仅提供连续搜索文本。

这可能,如何搜索这样的内容?

1 个答案:

答案 0 :(得分:0)

一种可能的解决方案是使用正则表达式。我们只需要在每个字母之间(以及字符串之前和之后)插入.*,这意味着“任何字符(行终止符除外)”。这似乎是用于搜索XCode完成的内容。

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];

要播放的样本,在之前插入:

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

以及之后:

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

输出:

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

用于构造字母数组的代码来自here。可以使用不同的解决方案来创建pattern,它可能不是最好的解决方案,但它是一个有效的解决方案。

<强>加成:

为了好玩(我很喜欢这样做),一种可能的方法为列表着色(我制作了一个NSAttributedString数组)来适应(没有完全测试或没有错误):

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