2013-02-26 9 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」メニューに似た検索機能ですマッチとして私は本当に意味があることを願っています。

Open Quickly Menu

+1

、私が探していた用語は「ファジー・マッチング」でした。 – squarefrog

答えて

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

+0

@squarefrog:どうぞよろしくお願いいたします。 –

関連する問題