web-dev-qa-db-ja.com

NSSortDescriptorを使用して配列を並べ替えたい

配列w.r.tデータベースのソートに関して問題があります:

NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:@"w" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject: sorter]; 

[mGlossaryArray sortUsingDescriptors:sortDescriptors]; 
[sorter release];

このデータベースには最初の大文字がいくつかあり、その大文字のために、適切なソートされた出力が表示されません。ここでは、データベースのテーブル列であるr.t "w"で配列をソートしています。ここに、出力のスクリーンショットを添付します。これは、「Cancer」が「c」よりも先に来ることを示していますが、これは正しくありません。大文字の単語のためにアルファベット順にソートされていません。

例えば。小文字に「able」と「aCid」がある場合、最初にaCidが表示され、次に「Able」と「a」のように1文字目が大文字の場合に最初に表示される場合もあります。ここでは、Ableが最初に表示されます。enter image description here

71
Prash.......

ここを見てください: ソート記述子の作成と使用

大文字と小文字を区別しないで比較できます。

NSSortDescriptor *sorter = [[[NSSortDescriptor alloc]
          initWithKey:@"w"
          ascending:YES
          selector:@selector(localizedCaseInsensitiveCompare:)] autorelease];
NSArray *sortDescriptors = [NSArray arrayWithObject: sorter];
[mGlossaryArray sortUsingDescriptors:sortDescriptors]; 
168
Hobbes the Tige

私が使用したのと同じようにNSSortDescriptorを使用するだけで、うまくいきました。

   NSSortDescriptor * sortByRank = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(caseInsensitiveCompare:)];
39
Prakash

-localizedStandardCompare:(NSString)を使用することをお勧めしますか?

「このメソッドは、Finderのような並べ替えが適切なリストやテーブルにファイル名またはその他の文字列が表示される場合に使用する必要があります。このメソッドの正確な並べ替え動作はロケールによって異なり、将来のリリースで変更される可能性があります。」

5

これを使用して、小文字も含む名前に従って配列をソートできます。

NSSortDescriptor *sorter = [NSSortDescriptor sortDescriptorWithKey:@"w" ascending:YES selector:@selector(caseInsensitiveCompare:)];

NSArray *sortDescriptors = [NSArray arrayWithObject:sorter]; 

[mGlossaryArray sortUsingDescriptors:sortDescriptors];

このコードは私にとってもうまく機能し、アルファベットに従って名前をソートすることもできます。アルファベットも小さい文字、つまり岩が多い、アジャイ、ジョン、ボブなどです.

3

これはあなたのためのトリックを行うと思います。そのドキュメントはここにあります: String Programming Guide

Appleが作成したこの小さな関数を追加します。

int finderSortWithLocale(id string1, id string2, void *locale)
{
    static NSStringCompareOptions comparisonOptions =
        NSCaseInsensitiveSearch | NSNumericSearch |
        NSWidthInsensitiveSearch | NSForcedOrderingSearch;

    NSRange string1Range = NSMakeRange(0, [string1 length]);

    return [string1 compare:string2
                    options:comparisonOptions
                    range:string1Range
                    locale:(NSLocale *)locale];
}

関数定義を必ずヘッダーにコピーしないと、ソートされた配列でコンパイルエラーが発生します。

ソートされた配列には、次のメソッドを使用します。

[mGlossaryArray sortedArrayUsingFunction:finderSortWithLocale context:[NSLocale currentLocale]];

結果は次のようになります。

  • c
  • キャビン
  • カフェ
  • 中国語
  • キリスト教
  • クリスマス
  • コークス
2
Hobbes the Tige

ロケールメソッドを使用したAppleのFinderソートの代替形式では、コンパレーターブロックを使用します。これは、ARC環境にいて、キャストのブリッジなどを処理したくない場合に役立ちます。

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"your_string_key" ascending:YES comparator:^NSComparisonResult(id obj1, id obj2) {
    NSStringCompareOptions comparisonOptions = NSCaseInsensitiveSearch | NSNumericSearch | NSWidthInsensitiveSearch | NSForcedOrderingSearch;
    NSRange string1Range = NSMakeRange(0, ((NSString *)obj1).length);
    return [(NSString *)obj1 compare: (NSString *)obj2 options: comparisonOptions range: string1Range locale: [NSLocale currentLocale]];
}];

NSArray *sortedArray = [originalArray sortedArrayUsingDescriptors:@[sortDescriptor]];

効率を上げるために、現在のロケールをローカル変数に保存することもお勧めします。

2
Ari Braginsky

このコードは私のためにうまく機能しています。

- (void)sortSearchResultWithInDocumentTypeArray:(NSMutableArray *)aResultArray basedOn:(NSString *)aSearchString {

    NSSortDescriptor * frequencyDescriptor =[[NSSortDescriptor alloc] initWithKey:aSearchString ascending:YES comparator:^(id firstDocumentName, id secondDocumentName) {

        static NSStringCompareOptions comparisonOptions =
        NSCaseInsensitiveSearch | NSNumericSearch |
        NSWidthInsensitiveSearch | NSForcedOrderingSearch;

        return [firstDocumentName compare:secondDocumentName options:comparisonOptions];
     }];

    NSArray * descriptors =    [NSArray arrayWithObjects:frequencyDescriptor, nil];
    [aResultArray sortUsingDescriptors:descriptors];
}
2
Varsheen