64 votes

Quel est le moyen le plus efficace de trier un NSSet?

Quel est le moyen le plus efficace de trier des objets dans une NSSet / NSMutableSet fonction d'une propriété des objets de l'ensemble? Actuellement, je le fais en parcourant chaque objet, en les ajoutant à un NSMutableArray et en triant ce tableau avec NSSortDescriptor .

115voto

cobbal Points 37900

essayez d'utiliser

 [[mySet allObjects] sortedArrayUsingDescriptors:descriptors];
 

Edit : Pour iOS ≥ 4.0 et Mac OS X ≥ 10.6, vous pouvez utiliser directement

 [mySet sortedArrayUsingDescriptors:descriptors];
 

15voto

Quinn Taylor Points 29688

Le "plus efficace" pour trier un ensemble d'objets varie selon ce que vous avez réellement dire. Le casual hypothèse (dont les réponses précédentes) est une sorte d'objets dans un ensemble. Dans ce cas, je dirais que c'est à peu près un tirage au sort entre ce que @cobbal suggère et à ce que vous est venu avec - probablement quelque chose comme ce qui suit:

NSMutableArray* array = [NSMutableArray arrayWithCapacity:[set count]];
for (id anObject in set)
    [array addObject:anObject];
[array sortUsingDescriptors:descriptors];

(Je dis que c'est un tirage au sort parce que @cobbal de l'approche crée deux autoreleased tableaux, de sorte que l'empreinte mémoire double. Ce n'est pas sans conséquence pour les petits ensembles d'objets, mais techniquement, ni l'approche est très efficace.)

Toutefois, si vous êtes trier les éléments dans le jeu plus d'une fois (et surtout si c'est une chose régulière) ce n'est certainement pas une approche efficace. Vous pouvez garder un NSMutableArray autour de et de le garder synchronisés avec le NSSet, puis appelez -sortUsingDescriptors: à chaque fois, mais même si le tableau est déjà trié, il aura toujours besoin d'un N comparaisons.

Cacao en lui-même n'a pas une approche efficace pour le maintien d'une collection dans l'ordre de tri. Java a un TreeSet classe qui conserve les éléments dans l'ordre chaque fois qu'un objet est inséré ou retiré, mais le Cacao n'est pas. C'est précisément ce problème qui m'a poussé à développer quelque chose de similaire pour mon propre usage.

Dans le cadre des structures de données-cadre dont j'ai hérité et remanié, j'ai créé un protocole et un peu d'implémentations pour les ensembles classés. Aucune des sous-classes concrètes de maintenir un ensemble d'objets distincts dans l'ordre de tri. Il y a encore des améliorations à l'être - le premier étant que le tri s'effectue sur la base du résultat de comparaison: (où chaque objet dans le jeu doit mettre en œuvre) et de ne pas encore accepter une NSSortDescriptor. (Une solution de contournement consiste à mettre en œuvre -compare: comparer la propriété de l'intérêt sur les objets.)

Un inconvénient possible est que ces classes sont (actuellement) pas de sous-classes de la nouvelle-écosse(Mutable), donc, si vous devez passer un NSSet, il ne sera pas ordonnée. (Le protocole n'ont -définir la méthode qui retourne un NSSet, ce qui est évidemment non ordonnée.) J'ai l'intention de rectifier que bientôt, comme je l'ai fait avec le NSMutableDictionary sous-classes dans le cadre. La rétroaction est certainement la bienvenue. :-)

8voto

bioffe Points 3486

Pour iOS ≥ 5.0 et Mac OS X ≥ 10.7, vous pouvez directement utiliser NSOrderedSet

2voto

stefanB Points 27796

NSSet est une collection non ordonnée d'objets. En regardant apple références Tableaux sont des collections ordonnées.

En regardant NSArray il y a une discussion avec des exemples de tri à http://developer.apple.com/documentation/Cocoa/Conceptual/Collections/Articles/sortingFilteringArrays ...

Exemple à partir du lien:

NSInteger alphabeticSort(id string1, id string2, void *reverse)
{
    if (*(BOOL *)reverse == YES) {
        return [string2 localizedCaseInsensitiveCompare:string1];
    }
    return [string1 localizedCaseInsensitiveCompare:string2];
}

// assuming anArray is array of unsorted strings

NSArray *sortedArray;

// sort using a selector
sortedArray =
    [anArray sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

// sort using a function
BOOL reverseSort = NO;
sortedArray =
    [anArray sortedArrayUsingFunction:alphabeticSort context:&reverseSort];

0voto

iTux Points 538

Vous ne pouvez pas trier NSSet, car "sortArrayUsingFunction:" définit le résultat sous la forme NSArray ... Et tous les conseils supérieurs ne fonctionnent qu'avec Array :)

 NSArray *myArray = [mySet sortedArrayUsingDescriptors:descriptors];
 

Travailler parfait, et pas besoin d'autre moyen :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X