2013-02-26 80 views
9

如何構造一個NSPredicate,在數組對象中的任何位置查找搜索項?我不能很好地解釋它,所以這裏是一個例子。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 Menu

+1

很顯然,我一直在尋找的術語是「模糊匹配」。 – squarefrog 2013-02-26 14:20:29

回答

19

在謂詞的LIKE字符串比較允許通配符*?,其中*匹配0或多個字符。因此,如果使用這樣的事情

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

然後將您的搜索文本

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

通過插入*之初,所有字符之間,並在原始搜索文本的結尾你可以在給定的順序使用

[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:@"*"]; 
       }]; 
+0

這正是我一直在尋找的。非常優雅的解決方案。謝謝。 – squarefrog 2013-02-26 14:40:16

+0

@squarefrog:不客氣。 – 2013-02-26 14:45:30