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
.
Réponses
Trop de publicités?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. :-)
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];