【问题标题】:How to search(Predicate) content from list like Xcode suggestion?如何从 Xcode 建议等列表中搜索(谓词)内容?
【发布时间】:2017-11-08 19:27:09
【问题描述】:

我想每个人都注意到 XCode 建议列表。检查此屏幕截图

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

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

仅提供连续搜索文本。

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

【问题讨论】:

    标签: ios xcode nspredicate search-suggestion


    【解决方案1】:

    一个可能的解决方案是为此使用正则表达式。我们只需要在每个字母之间(以及字符串之前和之后)插入.*,这意味着“任何字符(行终止符除外)”。似乎这就是 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];
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-04
      • 1970-01-01
      • 1970-01-01
      • 2020-12-01
      • 2017-10-27
      • 1970-01-01
      • 1970-01-01
      • 2020-07-25
      相关资源
      最近更新 更多