2010-12-06 11 views
2

私は言語アプリケーションを作成していますが、その言語に関連する長い語彙リストがあります(興味がある場合はドイツ語)。私は、アプリ内でドイツ語のテーブルビューをソートするか、英語の単語をソートするかを切り替える機能を持っています。 配列をソートするときに特定の文字列を無視する

私は次のように使用

:それは絶対に完璧に動作

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

- これによって私は意味は、まさに予想通り。しかし、私がこれを改善したいのは、動詞や名詞のような特定の単語があることです。「動かす」のように接頭辞が常に先行しています。名詞。だから私がやりたいことは、私のソートからこれらを除外してしまうのです。そうでなければ、私の動詞はアルファベット順にアルファベット順にソートされてしまいます。

私は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 

あなたはその後、NSArrayのためのあなたのソートセレクタとして@selector(compareWithoutArticles:)を使用することができます。

+0

これは、私が欲しいものに非常によく似ていますが、replaceOccurrencesOfStringと言ったときにコード内のビットによって混乱します。@ "das" withString @ "" ...実際には "das" (など)配列にとどまるために、私はそれを無視する必要があります。このコードはそれに対処していますか?途中で回答してくれてありがとう、私はあなたの助けに感謝します。 – Michaeljvdw

+0

うん、実際には、比較対象の文字列の複製を作成し、それを修正して記事と空白を削除します。つまり、単に文字列を変更するのではなく、代わりに 'compare:options:range:locale:'を使用してパフォーマンス上の理由から両方の文字列の部分範囲を比較する方が意味があるかもしれません。 –

1

まず、compare:を使用しないでください。代わりにlocalizedCompare:を使用してください。これは重要です。áaの直後か、またはzの後に表示されるかどうかは、言語によって異なります。 localizedCompare:がそれを処理します。ジャスティンが言うように

--edit

localizedStandardCompare:を使用するセレクタです!私はその方法を知らなかった。ドキュメントに書かれているように、localizedStandardCompare:localizedCompare:より多くなりますが、ドキュメントでは正確には何も言いません。

--end of edit

もっと必要な場合は、それを自分で実装する必要があります。その目的でカテゴリを使用できます。まずそれ

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

宣言してから、既存のクラスにメソッドを追加することができます

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

この方法でそれを実装。

メソッド名の前に、Appleが使用する内部メソッドを誤ってクラッシュさせないようにすることが重要です。

機能については、私が知る限り、自分で実装する必要があります。現在のロケールは[NSLocale currentLocale]で取得できます。あなたは知っている言語のためのより良い動作を実装することができますし、未知の言語の場合はデフォルトでlocalizedCompare:になります。

4

あなたは正しい道を歩いています。 (組み込みの)compareメソッドの代わりに使用したいのは、 "to"または "the"ビットが存在する場合はそれを排除することができる独自のメソッドを記述してから、既存のcompareメソッドを使用することです。私は、すべてのデータなどに-replaceOccurancesOfStringsを行う何とかなり

// 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

+1カスタム比較。文字列の先頭以外に "to"や "the"が現れる可能性がある場合は、Shaggyのコードを使用することもできますが、range.location == 0(またはエレガントでないsubstringWithRange isEqualToStringのもの、など) –

+0

@Matthew Frederick良い点。 'hasPrefix'を使うように変更しました。これは、' rangeOfString'が記事で始まる場合にのみそれを探していることを保証します。 –

+0

優れたソリューション。 –

0

:あなたは、以下の方法でNSStringに与えるカスタムカテゴリを使用して

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

あなたの呼び出しは次のようになります"To" - > "" - データをリロードしてください。

また、「歩く」ことは、「歩く(to)」に変更されていることを前提としています(ユーザーにはあまり混乱も生じません)アルファベット順にスクロールしています)。

関連する問題