NSPredicate匹配任何字符

时间:2013-02-26 14:07:37

标签: iphone objective-c nspredicate

如何构建一个在Arrays对象中的任何位置查找搜索词的NSPredicate?我无法正确解释,所以这是一个例子。

NSArray *array = @[@"Test String: Apple", @"Test String: Pineapple", @"Test String: Banana"];
NSString *searchText = @"Apple";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[cd] %@", searchText];
NSArray *filteredArray = [array filteredArrayUsingPredicate:predicate];
NSLog(@"filteredArray: %@", filteredArray);

// filteredArray: (
//    "Test String: Apple",
//    "Test String: Pineapple"
// )

但如果我使用NSString *searchText = @"Test Str Appl";,我的结果为零。我希望它匹配此字符串的相同结果。

我正在寻找的是一个类似于Xcode中的“Open Quickly”菜单的搜索功能,如果您的搜索字符串措辞正确,只要字母的顺序正确,则无关紧要一场比赛。我真的希望这是有道理的。

Open Quickly Menu

2 个答案:

答案 0 :(得分:20)

谓词中的LIKE字符串比较允许使用通配符*?,其中*匹配0个或更多字符。因此,如果您将搜索文本转换为

NSString *searchWithWildcards = @"*T*e*s*t* *S*t*r*A*p*p*l*";

在开头,所有字符之间插入*,并使用类似的内容在原始搜索文本的末尾插入

NSMutableString *searchWithWildcards = [NSMutableString stringWithFormat:@"*%@*", self.searchField.text];
if (searchWithWildcards.length > 3)
    for (int i = 2; i < self.searchField.text.length * 2; i += 2)
        [searchWithWildcards insertString:@"*" atIndex:i];

然后你可以使用

[NSPredicate predicateWithFormat:@"SELF LIKE[cd] %@", searchWithWildcards];

谓词按给定顺序搜索字符,并在它们之间使用任意其他字符。


转换可以使用以下代码完成:

NSMutableString *searchWithWildcards = [@"*" mutableCopy];
[searchText enumerateSubstringsInRange:NSMakeRange(0, [searchText length])
                   options:NSStringEnumerationByComposedCharacterSequences
                usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
                    [searchWithWildcards appendString:substring];
                    [searchWithWildcards appendString:@"*"];
                }];

答案 1 :(得分:0)

因为我看不懂objcC,所以写了自己的通配符函数。我们开始:

快捷键5

CoreData被提取到初始化数组中

var originalArray: [NSManagedObject] = []


extension myViewController: UISearchResultsUpdating {
    func updateSearchResults(for searchController: UISearchController) {
        filteredArray.removeAll(keepingCapacity: true)
        if searchController.searchBar.text!.isEmpty {
            filteredArray = originalArray
        } else {
            let filter = searchController.searchBar.text!
            var filterWithWildcards = ""
            for i in 0 ..< filter.length {
                if i == 0 {
                    filterWithFormat = "*"
                }
                filterWithFormat += filter[i] + "*"
            }
            print("filter: \(filter); filterWithWildcards: \(filterWithWildcards)") // filter: Mxmstrmnn; filterWithFormat: *M*x*m*s*t*r*m*n*n*
            myPredicate = NSPredicate(format: "EnterYourAttributeNameOfCoreDataEntity LIKE[c] %@", filterWithWildcards)
            let array = (people as NSArray).filtered(using: myPredicate!)
            filteredArray = array as! [NSManagedObject]
        }
        myTableView.reloadData()
}}

只要我保持字母顺序,filteredArray中的结果就会找到 Max Mustermann

要获取过滤器[i]的索引字母,我从这里https://stackoverflow.com/a/26775912/12035498

使用字符串扩展名
相关问题