Comment trier un NSArray par ordre alphabétique?


Réponses:


725

L'approche la plus simple consiste à fournir un sélecteur de tri ( documentation d' Apple pour plus de détails)

Objectif c

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

Rapide

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

Apple propose plusieurs sélecteurs pour le tri alphabétique:

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

Rapide

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

Référence


5
Le lien de documentation est obsolète, l'exemple de code n'est pas vraiment suffisant pour trier réellement le tableau. localizedCaseInsensitiveCompare: doit être défini d'une manière ou d'une autre.
M. Ryan

34
J'ai mis à jour le lien. Merci d'avoir fait remarquer cela. localizedCaseInsensitiveCompare: est une méthode de NSString et devrait être suffisante pour trier un tableau de chaînes.
Thomas Zoechling

1
Et cela peut être facilement appliqué à un tableau contenant des objets personnalisés (pas seulement NSString). Vous devez simplement vous assurer que tous les objets à l'intérieur de votre tableau ont implémenté le message spécifié par le sélecteur. Ensuite, dans ce message, vous appelez simplement la comparaison NSString pour les propriétés de votre objet que vous souhaitez comparer.
lgdev du

Ces choses simples ne doivent pas être aussi complexes.
Dmitry

276

Les autres réponses fournies ici mentionnent l'utilisation de @selector(localizedCaseInsensitiveCompare:) Cela fonctionne très bien pour un tableau de NSString, cependant si vous voulez étendre cela à un autre type d'objet et trier ces objets en fonction d'une propriété 'name', vous devriez le faire à la place:

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

Vos objets seront triés en fonction de la propriété de nom de ces objets.

Si vous souhaitez que le tri ne respecte pas la casse, vous devez définir le descripteur comme ceci

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

14
+1, merci. C'est drôle, c'est le cas d'utilisation le plus courant que la réponse acceptée.
Vinay W

4
cela trie d'abord les majuscules, puis les minuscules
HarshIT

+1, Le descripteur de tri avec le sélecteur est exactement ce que je voulais et aucune autre réponse ne l'a. Merci beaucoup mec
Ganesh Somani

1
J'obtiens une erreur lorsque j'essaie de trier un tableau de chaînes de cette façon, car ce namen'est pas une clé valide. Quelle clé dois-je utiliser pour trier les chaînes par ordre alphabétique avec un NSSortDescriptor?
temporary_user_name

27

Un moyen plus puissant de trier une liste de NSString pour utiliser des choses comme NSNumericSearch:

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

Combiné avec SortDescriptor, cela donnerait quelque chose comme:

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

Utilisez le code ci-dessous pour trier par ordre alphabétique:

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

Voici le journal de la 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

Une autre méthode simple pour trier un tableau de chaînes consiste à utiliser la descriptionpropriété NSString de cette façon:

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

1
Cela semble un peu inutile; il n'y a aucune raison de trier les chaînes de cette façon (et il y a probablement un impact sur les performances pour le faire), et pour d'autres objets, sa propriété de description est rarement utile à des fins de tri.
mah

3

Cela a déjà de bonnes réponses pour la plupart des fins, mais j'ajouterai la mienne qui est plus spécifique.

En anglais, normalement lorsque nous alphabétisons, nous ignorons le mot "the" au début d'une phrase. Ainsi, "Les États-Unis" seraient classés sous "U" et non "T".

Cela fait cela pour vous.

Il serait probablement préférable de les classer en catégories.

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

Je viens de regarder ces années plus tard, et j'ai réalisé qu'il devrait également inclure "un" et "une". Ceux-ci devraient être faciles à ajouter.
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];
    }
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.