2010-12-06 146 views
2

我正在編寫一個語言應用程序,並且我有一長串與該語言相關的詞彙表(如果有人感興趣,可以使用德語)。我有我的應用程序中的功能之間進行切換按德語單詞或英文單詞排序tableview。在對數組進行排序時忽略某些字符串

當我使用以下命令:

NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:type]; 
NSString *string = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]; 
NSArray *array = [[string componentsSeparatedByString:@"\n"] sortedArrayUsingSelector:@selector(compare:)]; 

它工作萬無一失了 - 我指的是,正是因爲預期。然而,我想改善這一點的是,有些詞語,比如動詞或名詞,前面總是有前綴,比如「to」,比如「做某事」,或者「the」名詞。所以我想要做的是以某種方式排除我的排序,因爲否則我會在我的數組的「t」部分按字母順序排序所有動詞,這不是很方便用戶。

我已經瀏覽了關於NSString和NSArray的Apple文檔,因爲這是compare函數的地方(除非我非常誤會),而且我還沒有找到任何對我有意義的方法。這是我第一次做這樣的數據處理,所以我可能會錯過簡單的東西,所以我非常感謝一些幫助。

非常感謝

Michaeljvdw

回答

1

你可能有一些運氣localizedCompare:localizedStandardCompare:,但我不認爲像你想要的任何一項都將去掉冠詞和介詞。相反,你可能會定義上NSString提供分揀您的特定風格的類別正在尋找:

@interface NSString (MySortAdditions) 
- (NSComparisonResult)compareWithoutArticles:(NSString *)other; 
@end 

@implementation NSString (MySortAdditions) 
- (NSComparisonResult)compareWithoutArticles:(NSString *)other { 
    NSMutableString *mutableSelf = [NSMutableString stringWithString:self]; 
    [mutableSelf 
     replaceOccurrencesOfString:@"das" 
     withString:@"" 
     options:NSCaseInsensitiveSearch 
     range:NSMakeRange(0, [mutableSelf length]) 
    ]; 

    ... 

    // delete articles from 'other' too 

    NSCharacterSet *trimSet = [NSCharacterSet whitespaceAndNewlineCharacterSet]; 
    NSString *trimmedSelf = [mutableSelf stringByTrimmingCharactersInSet:trimSet]; 
    NSString *trimmedOther = ...; 

    return [trimmedSelf localizedCaseInsensitiveCompare:trimmedOther]; 
} 
@end 

然後可以使用@selector(compareWithoutArticles:)爲您的排序選擇了NSArray

+0

這看起來非常像我想要的,但是當你說replaceOccurrencesOfString時:@「das」withString @「」...因爲我實際上需要「das」 (等)留在數組中,我只是需要從排序中忽略它。這個代碼解決了這個問題嗎感謝您的回答,感謝您的幫助。 – Michaeljvdw 2010-12-06 08:02:54

+0

是的,該代碼實際上做的是創建被比較的字符串的副本,然後修改這些以刪除任何文章和空白。也就是說,回想起來,出於性能原因,可能更有意義*不*修改字符串,而是使用`compare:options:range:locale:`來比較兩個字符串的子範圍。 – 2010-12-06 09:18:06

1

首先,請勿使用compare:。改爲使用localizedCompare:。這很重要,因爲á是否出現在a之後或z之後作爲單獨的字母取決於語言。 localizedCompare:照顧到這一點。

--edit

賈斯汀說,localizedStandardCompare:是要使用的選擇!我不知道那種方法。正如文檔中所寫,localizedStandardCompare:確實比localizedCompare:多,但該文檔並未明確說明它的功能。

- 編輯結束

如果您想要更多,則需要自行實施。您可以使用類別用於此目的。首先聲明它

@interface NSString (MichaelsSuperCompareCategory) 
     -(NSComparisonResult)michaelsSuperCompare:(NSString*)string; 
    @end 

,然後實現它

@interface NSString (MichaelsSuperCompareCategory) 
     -(NSComparisonResult)michaelsSuperCompare:(NSString*)string{ 
      ... 
     } 
    @end 

這樣您就可以添加方法,以現有的類。然後你可以使用

NSArray *array = [[string componentsSeparatedByString:@"\n"] 
           sortedArrayUsingSelector:@selector(michaelsSuperCompare:)]; 

的東西與衆不同,不要意外地與蘋果公司使用的內部方法崩潰的前綴的方法名是很重要的。

至於功能,你需要自己實現,據我所知。您可以使用[NSLocale currentLocale]獲取當前語言環境。您可以針對您所知的語言實施更好的行爲,然後默認爲localizedCompare:以處理未知語言。

4

你在正確的軌道上。你想用什麼來代替(內置的)compare方法是編寫你自己的方法,它可以消除「to」或「the」位(如果存在的話),然後使用現有的compare方法。

您的通話將是這個樣子:

NSArray *array = [[string componentsSeparatedByString:@"\n"] sortedArrayUsingSelector:@selector(myCompare:)]; 

使用你給NSString以下方法自定義類別:

// This method can be exposed in a header 
- (NSComparisonResult)myCompare:(NSString*)aString 
{ 
NSString* selfTrimmed = [self removeArticles]; 
NSString* aStringTrimmed = [s2 removeArticles]; 
return [self compare:aString]; 
} 

// This method can be kept private in the .m implementation 
- (NSString*)removeArticles 
{ 
    NSRange range = NSMakeRange(NSNotFound, 0); 
    if ([self hasPrefix:@"to "]) 
    { 
    range = [self rangeOfString:@"to "]; 
    } 
    else if ([self hasPrefix:@"the "]) 
    { 
    range = [self rangeOfString:@"the "]; 
    } 

if (range.location != NSNotFound) 
{ 
    return [self substringFromIndex:range.length]; 
} 
else 
{ 
    return self; 
} 
} 
0

我會在一定程度上的所有數據,例如做-replaceOccurancesOfStrings 「至」 - >「」 - 然後重新載入數據。 (或者這可以在文本編輯器中)

另一件需要考慮的事情是讓例如'走'變成'走(到)',這可以提前完成(並且也會減少用戶的困惑因爲它們按字母順序滾動)。

相關問題