Ich möchte ein Array mit NSSortDescriptor sortieren

72

Ich habe ein Problem beim Sortieren einer Array-Datenbank:

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

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

Hier in der Datenbank gibt es einige erste Großbuchstaben, und aufgrund dieses Großbuchstabens wird mir keine ordnungsgemäß sortierte Ausgabe angezeigt. Hier sortiere ich ein Array mit rt "w", das meine Tabellenspalte in der Datenbank ist. Hier habe ich den Screenshot für die Ausgabe angehängt, der besagt, dass "Krebs" an erster Stelle steht als "c", aber dies ist nicht korrekt, es wird aufgrund der großgeschriebenen Wörter nicht alphabetisch sortiert.

z.B. Wenn es "in der Lage" in Kleinbuchstaben und "aCid" gibt, wird zuerst aCid und dann in der Lage angezeigt, und es gibt auch einen Fall, in dem der erste Buchstabe, wenn er Großbuchstaben enthält, zuerst kommt, z. B. "Able" und "a". Hier wird Able zuerst angezeigt.Geben Sie hier die Bildbeschreibung ein

Prash .......
quelle

Antworten:

168

Schauen Sie hier: Erstellen und Verwenden von Sortierdeskriptoren

Sie können zwischen Groß- und Kleinschreibung unterscheiden.

NSSortDescriptor *sorter = [[[NSSortDescriptor alloc]
          initWithKey:@"w"
          ascending:YES
          selector:@selector(localizedCaseInsensitiveCompare:)] autorelease];
NSArray *sortDescriptors = [NSArray arrayWithObject: sorter];
[mGlossaryArray sortUsingDescriptors:sortDescriptors]; 
Hobbes the Tige
quelle
Aber es sortiert immer noch nicht, es gibt mir zuerst alles Kapital und dann Kleinbuchstaben
Prash .......
Können Sie eine Probe der gewünschten Art geben?
Hobbes the Tige
Schauen Sie sich die Bildanzeigen an, es gibt mir die unsortierte Ausgabe, als ob in diesem Fall "c" an erster Stelle stehen sollte, aber Krebs an erster Stelle steht. Bitte helfen Sie mir in diesem Fall.
Prash .......
Ich hatte das gleiche Problem, aber die angegebene Lösung funktioniert in meinem Fall einwandfrei.
Ben Groot
2
Perfekte Antwort. "localizedCaseInsensitiveCompare" stellt sicher, dass Zeichenfolgen, die mit Fremdzeichen beginnen (z. B. das französische E-Akut), auch in der Liste korrekt sortiert angezeigt werden und auch mit Groß- / Kleinbuchstaben gut umgehen können.
Mike Gledhill
39

Verwenden Sie einfach NSSortDescriptor wie ich und es hat gut funktioniert.

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

Darf ich vorschlagen, -localizedStandardCompare: (NSString) zu verwenden?

"Diese Methode sollte immer dann verwendet werden, wenn Dateinamen oder andere Zeichenfolgen in Listen und Tabellen angezeigt werden, in denen eine Finder-ähnliche Sortierung angebracht ist. Das genaue Sortierverhalten dieser Methode ist in verschiedenen Ländereinstellungen unterschiedlich und kann in zukünftigen Versionen geändert werden."

Christian Kienle
quelle
3

Sie können dies verwenden, um ein Array nach einem Namen zu sortieren, der auch einen kleinen Buchstaben enthält :

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

NSArray *sortDescriptors = [NSArray arrayWithObject:sorter]; 

[mGlossaryArray sortUsingDescriptors:sortDescriptors];

Dieser Code funktioniert gut für mich, um Namen nach Alphabeten zu sortieren, die auch einen kleinen Charakter haben, z. B. Rocky, Ajay, John, Bob usw.

Lalit Kumar Maurya
quelle
2

Ich denke, das wird den Trick für Sie tun. Die Dokumentation dazu finden Sie hier: String Programming Guide

Fügen Sie diese kleine Funktion von Apple hinzu.

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];
}

Stellen Sie sicher, dass Sie die Funktionsdefinition in Ihren Header kopieren. Andernfalls wird ein Kompilierungsfehler für Ihr sortiertes Array angezeigt.

Verwenden Sie für Ihr sortiertes Array die folgende Methode:

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

Ihre Ergebnisse sehen folgendermaßen aus:

  • c
  • Kabine
  • Cafe
  • Krebs
  • Chinesisch
  • Christentum
  • Weihnachten
  • Koks
Hobbes the Tige
quelle
2

Dieser Code funktioniert gut für mich.

- (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];
}
Varsheen
quelle
2

Eine alternative Form von Apples Finder-Sortierung mit Gebietsschemamethode verwendet den Komparatorblock. Dies ist hilfreich, wenn Sie sich in einer ARC-Umgebung befinden und sich nicht mit Bridging Casts usw. befassen möchten.

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

Ich würde auch empfehlen, das aktuelle Gebietsschema aus Effizienzgründen in einer lokalen Variablen zu speichern.

Ari Braginsky
quelle