2013-08-05 10 views
1

目前我使用這個通過我的字典的數組(從plist文件)搜索:Objective-C - 比NSCaseInsensitiveSearch更好的搜索?關鍵詞? NSPredicate?

for(NSDictionary *wine in mainArray) 
    { 
     NSString *wineName = [wine objectForKey:@"name"]; 
     NSRange range = [wineName rangeOfString:searchText options:NSCaseInsensitiveSearch]; 
     if(range.location != NSNotFound) 
      [searchArray addObject:wine]; 
    } 

在這個問題上,我要這個plist中作爲一個例子:

<array> 
<dict> 
    <key>name</key> 
    <string>Banana One (Yellow)</string> 
    <key>value</key> 
    <string>1</string> 
</dict> 
<dict> 
    <key>name</key> 
    <string>Apple Two (White)</string> 
    <key>value</key> 
    <string>2</string> 
</dict> 
<dict> 
    <key>name</key> 
    <string>Pineapple Three (Orange)</string> 
    <key>value</key> 
    <string>3</string> 
</dict> 
<dict> 
</array> 

(千萬不在乎值)

好吧,當我使用UISearchBar與NSCaseInsensitiveSearch我可以簡單地搜索整個數組([email protected]"name")而不用考慮Case。好!

比如我可以搜索:@"banana"和發現:香蕉一個(黃色)

,我可以搜索:@"two"和發現:蘋果二(白)

,我可以搜索:@"banana一個」,並找到:香蕉一個(黃色)

我還可以搜索:@"Orange"並找到:菠蘿三(橙色)

但只有當變奏h是在正確的順序

我不能搜索:@"One Banana"@"Yellow One"@"Yellow Banana" 我真的很希望能夠搜索到這個樣子,也許使用關鍵字?

也許這樣的事情?:

for(NSDictionary *wine in mainArray) 
{ 
NSArray *myArray = [searchText componentsSeparatedByString:@" "]; 
    NSString *wineName = [wine objectForKey:@"name"]; 
    NSRange range = [wineName rangeOfString:myArray options:NSCaseInsensitiveSearch]; 
    if(range.location != NSNotFound) 
     [searchArray addObject:wine]; 
} 

我知道,這真的不會工作,但我想你明白我的意思? 所以,如何能夠搜索的例子:@"one banana"找到並找到:Banana One(黃色)

回答

1

我制定了以下解決方案,使用NSPredicate

NSArray *objects = @[@"Banana One",@"Apple Two"]; 
    NSString *searchString = @"one banana"; 
    NSArray *searchComoponents = [searchString componentsSeparatedByString:@" "]; 

    NSMutableString *format = [NSMutableString stringWithFormat:@"SELF CONTAINS[c] \"%@\"",[NSString stringWithFormat:@"%@",searchComoponents[0]]]; 
    for (int i = 1; i < searchComoponents.count; i++) { 
     [format appendFormat:@" AND SELF CONTAINS[c] \"%@\"",[NSString stringWithFormat:@"%@",searchComoponents[i]]]; 
    } 
    NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"%@",format]]; 
    NSArray *filtered = [objects filteredArrayUsingPredicate:predicate]; 

對於一個簡短的說明:SELF是數組,應校對,CONTAINS長相,左對象是否包含合適的對象在當前對象,[c]讓這一切CASEINSENSITIVE。 所以在搜索字符串的每個關鍵字,您添加條件到predicateformat,以便在最後,你應該有一個NSPredicate這種格式: SELF包含:[C] object1和自我包含:[C] 對象2 .... 最後一行使用此NSPredicate創建一個已過濾的數組。有關謂詞格式的更多信息,請參閱here

0

也許你應該拆分NSString「Banana One(Yellow)」在一個數組(「Banana」,「One」 「(黃色)」),並檢查其中是否包含您的搜索文本。

NSString *searchText = @"One"; 
    NSString *txt = @"Banana One (Yellow)"; 
    NSArray* splitString = [txt componentsSeparatedByString:@" "]; 
    for(int i = 0; i < [splitString count]; i++){ 
     if([[splitString objectAtIndex:i] rangeOfString:searchText].location != NSNotFound) { 
      return txt; 
     } 
    } 
1

解決

感謝DevFan的回答! 我需要編輯一些東西,例如SELF到SELF.name,以在我的字典數組中指定鍵。

NSArray *searchComoponentsWithEmptyStrings = [searchText componentsSeparatedByString:@" "]; 
     NSMutableArray *searchComoponents = [searchComoponentsWithEmptyStrings mutableCopy]; 
     [searchComoponents removeObject:@""]; //remove empty strings from the array (only works with NSMutableArray) 

     NSMutableString *format = [NSMutableString stringWithFormat:@"SELF.name CONTAINS[c] '%@'",[NSString stringWithFormat:@"%@",searchComoponents[0]]]; 
     for (int i = 1; i < searchComoponents.count; i++) { 
      [format appendFormat:@"AND SELF.name CONTAINS[c] '%@'",[NSString stringWithFormat:@"%@",searchComoponents[i]]]; 
     } 
     NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"%@",format]]; 
     searchArray = [mainArray filteredArrayUsingPredicate:predicate]; 

,現在我也可以(在末尾用空格)搜索@「香蕉」,並從中找到一個香蕉(黃色)