Wie sortiere ich ein NSArray alphabetisch?

375

Wie kann ich ein gefülltes Array [UIFont familyNames]in alphabetischer Reihenfolge sortieren ?

DotSlashSlash
quelle

Antworten:

725

Der einfachste Ansatz besteht darin, eine Sortierauswahl bereitzustellen ( Einzelheiten finden Sie in der Apple-Dokumentation ).

Ziel c

sortedArray = [anArray sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

Schnell

let descriptor: NSSortDescriptor = NSSortDescriptor(key: "YourKey", ascending: true, selector: "localizedCaseInsensitiveCompare:")
let sortedResults: NSArray = temparray.sortedArrayUsingDescriptors([descriptor])

Apple bietet verschiedene Selektoren für die alphabetische Sortierung:

  • compare:
  • caseInsensitiveCompare:
  • localizedCompare:
  • localizedCaseInsensitiveCompare:
  • localizedStandardCompare:

Schnell

var students = ["Kofi", "Abena", "Peter", "Kweku", "Akosua"]
students.sort()
print(students)
// Prints "["Abena", "Akosua", "Kofi", "Kweku", "Peter"]"

Referenz

Thomas Zoechling
quelle
5
Der Dokumentationslink ist veraltet. Das Codebeispiel reicht nicht aus, um das Array tatsächlich zu sortieren. localizedCaseInsensitiveCompare: muss irgendwie definiert werden.
M. Ryan
34
Ich habe den Link aktualisiert. Vielen Dank für den Hinweis. localizedCaseInsensitiveCompare: ist eine Methode von NSString und sollte ausreichen, um ein Array von Zeichenfolgen zu sortieren.
Thomas Zoechling
1
Dies kann problemlos auf ein Array angewendet werden, das benutzerdefinierte Objekte enthält (nicht nur NSString). Sie müssen nur sicherstellen, dass alle Objekte in Ihrem Array die vom Selektor angegebene Nachricht implementiert haben. Dann rufen Sie in dieser Nachricht einfach den NSString-Vergleich für die Eigenschaften Ihres Objekts auf, die Sie vergleichen möchten.
lgdev
Solche einfachen Dinge dürfen nicht so komplex sein.
Dmitry
276

In den anderen hier angegebenen Antworten wird die Verwendung von @selector(localizedCaseInsensitiveCompare:) Dies funktioniert hervorragend für ein Array von NSString. Wenn Sie dies jedoch auf einen anderen Objekttyp erweitern und diese Objekte nach einer 'name'-Eigenschaft sortieren möchten, sollten Sie stattdessen Folgendes tun:

NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
sortedArray=[anArray sortedArrayUsingDescriptors:@[sort]];

Ihre Objekte werden nach der Namenseigenschaft dieser Objekte sortiert.

Wenn Sie möchten, dass bei der Sortierung die Groß- und Kleinschreibung nicht berücksichtigt wird, müssen Sie den Deskriptor wie folgt festlegen

NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES selector:@selector(caseInsensitiveCompare:)];
JP Hribovsek
quelle
14
+1, danke. Komisch, dass dies der häufigere Anwendungsfall ist als die akzeptierte Antwort.
Vinay W
4
Dies sortiert zuerst Großbuchstaben und dann Kleinbuchstaben
HarshIT
+1, Der Sortierdeskriptor zusammen mit dem Selektor ist genau das, was ich wollte, und keine andere Antwort hatte dies. Vielen Dank Mann
Ganesh Somani
1
Ich erhalte eine Fehlermeldung, wenn ich versuche, ein Array von Zeichenfolgen auf diese Weise zu sortieren, da dies namekein gültiger Schlüssel ist. Mit welchem ​​Schlüssel sortiere ich Zeichenfolgen mit einem NSSortDescriptor alphabetisch?
temporärer_Benutzername
27

Eine leistungsfähigere Methode zum Sortieren einer Liste von NSString, um Dinge wie NSNumericSearch zu verwenden:

NSArray *sortedArrayOfString = [arrayOfString sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
            return [(NSString *)obj1 compare:(NSString *)obj2 options:NSNumericSearch];
        }];

In Kombination mit SortDescriptor würde dies Folgendes ergeben:

NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES comparator:^NSComparisonResult(id obj1, id obj2) {
        return [(NSString *)obj1 compare:(NSString *)obj2 options:NSNumericSearch];
    }];
NSArray *sortedArray = [anArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]];
Ben G.
quelle
10

Verwenden Sie den folgenden Code zum Sortieren in alphabetischer Reihenfolge:

    NSArray *unsortedStrings = @[@"Verdana", @"MS San Serif", @"Times New Roman",@"Chalkduster",@"Impact"];

    NSArray *sortedStrings =
    [unsortedStrings sortedArrayUsingSelector:@selector(compare:)];

    NSLog(@"Unsorted Array : %@",unsortedStrings);        
    NSLog(@"Sorted Array : %@",sortedStrings);

Unten ist das Konsolenprotokoll:

2015-04-02 16:17:50.614 ToDoList[2133:100512] Unsorted Array : (
    Verdana,
    "MS San Serif",
    "Times New Roman",
    Chalkduster,
    Impact
)

2015-04-02 16:17:50.615 ToDoList[2133:100512] Sorted Array : (
    Chalkduster,
    Impact,
    "MS San Serif",
    "Times New Roman",
    Verdana
)
Jayprakash Dubey
quelle
10

Eine andere einfache Methode zum Sortieren eines Arrays von Zeichenfolgen besteht darin, die NSString- descriptionEigenschaft folgendermaßen zu verwenden:

NSSortDescriptor *valueDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"description" ascending:YES];
arrayOfSortedStrings = [arrayOfNotSortedStrings sortedArrayUsingDescriptors:@[valueDescriptor]];
Lisarien
quelle
1
Das scheint ein bisschen nutzlos; Es gibt keinen Grund, Zeichenfolgen auf diese Weise zu sortieren (und es gibt wahrscheinlich einen Leistungseinbruch dafür), und für andere Objekte ist die Beschreibungseigenschaft für Sortierzwecke selten nützlich.
mah
3

Dies hat für die meisten Zwecke bereits gute Antworten, aber ich werde meine hinzufügen, die spezifischer ist.

Im Englischen ignorieren wir normalerweise beim Alphabetisieren das Wort "the" am Anfang einer Phrase. "Die Vereinigten Staaten" würden also unter "U" und nicht unter "T" bestellt.

Das macht das für dich.

Es wäre wahrscheinlich am besten, diese in Kategorien einzuteilen.

// Sort an array of NSStrings alphabetically, ignoring the word "the" at the beginning of a string.

-(NSArray*) sortArrayAlphabeticallyIgnoringThes:(NSArray*) unsortedArray {

    NSArray * sortedArray = [unsortedArray sortedArrayUsingComparator:^NSComparisonResult(NSString* a, NSString* b) {

        //find the strings that will actually be compared for alphabetical ordering
        NSString* firstStringToCompare = [self stringByRemovingPrecedingThe:a];
        NSString* secondStringToCompare = [self stringByRemovingPrecedingThe:b];

        return [firstStringToCompare compare:secondStringToCompare];
    }];
    return sortedArray;
}

// Remove "the"s, also removes preceding white spaces that are left as a result. Assumes no preceding whitespaces to start with. nb: Trailing white spaces will be deleted too.

-(NSString*) stringByRemovingPrecedingThe:(NSString*) originalString {
    NSString* result;
    if ([[originalString substringToIndex:3].lowercaseString isEqualToString:@"the"]) {
        result = [[originalString substringFromIndex:3] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    }
    else {
        result = originalString;
    }
    return result;
}
narco
quelle
Ich habe mir das erst Jahre später angesehen und festgestellt, dass es auch "a" und "an" enthalten sollte. Diese sollten leicht hinzuzufügen sein.
Narco
1
-(IBAction)SegmentbtnCLK:(id)sender
{ [self sortArryofDictionary];
    [self.objtable reloadData];}
-(void)sortArryofDictionary
{ NSSortDescriptor *sorter;
    switch (sortcontrol.selectedSegmentIndex)
    {case 0:
            sorter=[[NSSortDescriptor alloc]initWithKey:@"Name" ascending:YES];
            break;
        case 1:
            sorter=[[NSSortDescriptor alloc]initWithKey:@"Age" ascending:YES];
            default:
            break; }
    NSArray *sortdiscriptor=[[NSArray alloc]initWithObjects:sorter, nil];
    [arr sortUsingDescriptors:sortdiscriptor];
    }
deepa
quelle