Come ordinare alfabeticamente un NSArray?


Risposte:


725

L'approccio più semplice è fornire un selettore di ordinamento ( la documentazione di Apple per i dettagli)

Objective-C

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

veloce

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

Apple offre diversi selettori per l'ordinamento alfabetico:

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

veloce

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

Riferimento


5
Il collegamento alla documentazione non è aggiornato, l'esempio di codice non è abbastanza per ordinare effettivamente l'array. localizedCaseInsensitiveCompare: deve essere definito in qualche modo.
M. Ryan,

34
Ho aggiornato il link. Grazie per la segnalazione. localizedCaseInsensitiveCompare: è un metodo di NSString e dovrebbe essere sufficiente per ordinare una matrice di stringhe.
Thomas Zoechling,

1
E questo può essere facilmente applicato a un array contenente qualsiasi oggetto personalizzato (non solo NSString). Devi solo assicurarti che tutti gli oggetti all'interno dell'array abbiano implementato il messaggio specificato dal selettore. Quindi all'interno di questo messaggio basta chiamare il confronto NSString per le proprietà dell'oggetto che si desidera confrontare.
lgdev,

Tali cose semplici non devono essere così complesse.
Dmitry,

276

Le altre risposte fornite qui menzionano l'utilizzo di @selector(localizedCaseInsensitiveCompare:) This funziona alla grande per una matrice di NSString, tuttavia se si desidera estenderlo a un altro tipo di oggetto e ordinare tali oggetti in base a una proprietà 'name', è necessario fare invece questo:

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

I tuoi oggetti verranno ordinati in base alla proprietà name di tali oggetti.

Se si desidera che l'ordinamento non faccia distinzione tra maiuscole e minuscole, è necessario impostare il descrittore in questo modo

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

14
+1, grazie. Divertente questo è il caso d'uso più comune della risposta accettata.
Vinay W,

4
questo ordina prima le lettere maiuscole e poi quelle minuscole
HarshIT

+1, il descrittore di ordinamento insieme al selettore è esattamente quello che volevo e nessun'altra risposta aveva questo. Grazie mille amico
Ganesh Somani

1
Ottengo un errore quando provo a ordinare un array di stringhe in questo modo, perché namenon è una chiave valida. Quale chiave devo usare per ordinare le stringhe in ordine alfabetico con un NSSortDescriptor?
temporaneo

27

Un modo più potente di ordinare un elenco di NSString per usare cose come NSNumericSearch:

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

In combinazione con SortDescriptor, ciò darebbe qualcosa del tipo:

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

10

Utilizzare il codice seguente per ordinare in ordine alfabetico:

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

Di seguito è riportato il registro della console:

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
)

10

Un altro metodo semplice per ordinare una matrice di stringhe consiste nell'utilizzare la descriptionproprietà NSString in questo modo:

NSSortDescriptor *valueDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"description" ascending:YES];
arrayOfSortedStrings = [arrayOfNotSortedStrings sortedArrayUsingDescriptors:@[valueDescriptor]];

1
Sembra un po 'inutile; non c'è motivo di ordinare le stringhe in questo modo (e probabilmente c'è un hit prestazionale per farlo), e per altri oggetti, la sua proprietà description è raramente utile ai fini dell'ordinamento.
Mah,

3

Questo ha già buone risposte per la maggior parte degli scopi, ma aggiungerò la mia, che è più specifica.

In inglese, normalmente quando alfabetizziamo, ignoriamo la parola "the" all'inizio di una frase. Quindi "Gli Stati Uniti" sarebbero ordinati sotto "U" e non "T".

Questo fa per te.

Probabilmente sarebbe meglio metterli in categorie.

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

Ho appena guardato questo anni dopo, e mi sono reso conto che dovrebbe includere anche "a" e "an". Questi dovrebbero essere facili da aggiungere.
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];
    }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.