8

iOS UITableView オブジェクトを並べ替えようとしています。現在、次のコードを使用しています。

// Sort terms alphabetically, ignoring case
[self.termsList sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

これにより、大文字と小文字を区別せずにリストが並べ替えられます。ただし、句読点も無視するとよいでしょう。例えば:

c.a.t.
car
cat

次のようにソートする必要があります。

car
c.a.t.
cat

(実際には、2 匹の猫 (猫または猫) のどちらが最初に来るかは問題ではありません。

これを回避する簡単な方法はありますか?解決策には、文字列から英数字のみを抽出し、それらを比較してから、英数字以外の文字を再度含めて元の状態に戻すことが含まれると思います。

実際のところ、私が本当に気にかけている文字はピリオド (.) だけですが、すべての句読点を簡単にカバーする解決策があれば、知っておくと役に立ちます。

注: 1か月前に Java についてまったく同じ質問をしました。現在、Objective-C で同じソリューションを作成しています。これを簡単にするiOS APIで利用できるトリックがあるのだろうか...

編集:次のコードを使用して句読点を削除し、並べ替えた別の配列に入力しようとしました(@tigueroが提案)。ただし、最後のステップを実行する方法がわかりません。最初の配列を2番目の順序に従って実際にソートすることです。これが私のコードです:

    NSMutableArray *arrayWithoutPunctuation = [[NSMutableArray alloc] init];
    for (NSString *item in arrayWithPunctuation)
    {
        // Replace hyphens/periods with spaces
        item = [item stringByReplacingOccurrencesOfString:@"-" withString:@" "]; // ...hyphens
        item = [item stringByReplacingOccurrencesOfString:@"." withString:@" "]; // ...periods
        [arrayWithoutPunctuation addObject:item];
    }
    [arrayWithoutPunctuation sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

これはソートされた「arrayWithoutPunctuation」を提供しますが、もちろん句読点は含まれていません。これはうまくソートされていませんが、そもそも配列にとって重要な句読点が含まれていないため、これは良くありません。私がする必要があるのは、「arrayWithoutPunctuation」の順序に従って「arrayWithPunctuation」をソートすることです...助けていただければ幸いです。

4

3 に答える 3

9

で比較ブロックを使用するNSArrayと、コードは次のようになります。

NSArray* yourStringList = [NSArray arrayWithObjects:@"c.a.t.", @"car", @"cat", nil];
NSArray* yourStringSorted = [yourStringList sortedArrayUsingComparator:^(id a, id b){
        NSString* as = (NSString*)a;
        NSString* bs = (NSString*)b;

        NSCharacterSet *unwantedChars = [NSCharacterSet characterSetWithCharactersInString:@"\\.:',"];
        //Remove unwanted chars
        as = [[as componentsSeparatedByCharactersInSet: unwantedChars] componentsJoinedByString: @""];
        bs = [[as componentsSeparatedByCharactersInSet: unwantedChars] componentsJoinedByString: @""];

        // make the case insensitive comparison btw your two strings
        return [as caseInsensitiveCompare: bs];
    }];

これは最も効率的なコードではないかもしれません。実際には、最初に配列を反復処理し、不要な文字をすべて削除しselectorて、caseInsensitiveCompareメソッドで a を使用するという別のオプションがあります。

 NSString* yourStringSorted = [yourStringList sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
于 2012-10-24T22:41:53.203 に答える
2

これは少しクリーンで、もう少し効率的です。

NSArray* strings = @[@".....c",@"a.",@"a",@"b",@"b...",@"a..,"];
NSArray* sorted_strings = [strings sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    NSString* a = [obj1 stringByTrimmingCharactersInSet:[NSCharacterSet punctuationCharacterSet]];
    NSString* b = [obj2 stringByTrimmingCharactersInSet:[NSCharacterSet punctuationCharacterSet]];
    return [a caseInsensitiveCompare:b];
}];

本当の効率のために、句読点を無視する比較メソッドを作成して、比較のためだけにメモリ割り当てが必要ないようにします。

于 2012-11-06T10:39:03.977 に答える
1

私の解決策は、各文字列を2 つのプロパティを持つカスタム オブジェクトにグループ化することです。

  • 元の文字列
  • 句読点のない文字列

...そして、句読点のない文字列に基づいてオブジェクトを並べ替えます。

Objective C には、それを行う便利な方法がいくつかあります。このオブジェクトに 2 つの文字列があるとします。

NSString *myString;
NSString *modified;

まず、カスタム オブジェクトを配列に追加します。

NSMutableArray *myStrings = [[NSMutableArray alloc] init];
[myStrings addObject: ...];

次に、便利な NSSortDescriptor を使用して、変更された変数で配列を並べ替えます。

//You can specify the variable name to sort by
//Sorting is done according to the locale using localizedStandardCompare
NSSortDescriptor *mySortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"modified" ascending:YES selector:@selector(localizedStandardCompare:)];
[myStrings sortedArrayUsingDescriptors:@[ mySortDescriptor ]];

出来上がり!オブジェクト (および文字列) が並べ替えられます。 NSSortDescriptor の詳細については...

于 2012-10-30T23:37:30.200 に答える