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

Quel est le moyen le plus efficace de sortinger des objects dans un NSSet / NSMutableSet fonction d’une propriété des objects de l’ensemble? En ce moment, je le fais en parcourant chaque object, en les ajoutant à un NSMutableArray et en NSSortDescriptor ce tableau avec NSSortDescriptor .

essayez d’utiliser

 [[mySet allObjects] sortedArrayUsingDescriptors:descriptors]; 

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

 [mySet sortedArrayUsingDescriptors:descriptors]; 

Le “moyen le plus efficace” de sortinger un ensemble d’objects varie en fonction de ce que vous voulez dire. L’hypothèse désinvolte (que les réponses précédentes font) est une sorte unique d’objects dans un ensemble. Dans ce cas, je dirais que c’est plutôt un mélange entre ce que suggère @cobbal et ce que vous avez imaginé – probablement quelque chose comme ceci:

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

(Je dis que c’est une approche parce que l’approche de @cobbal crée deux tableaux auto-libérés, donc l’empreinte mémoire double. Ceci est sans conséquence pour les petits ensembles d’objects, mais techniquement, aucune des deux approches n’est très efficace.)

Cependant , si vous sortingez les éléments dans le jeu plus d’une fois (et surtout si c’est une chose courante), ce n’est certainement pas une approche efficace. Vous pouvez conserver un NSMutableArray et le garder synchronisé avec le NSSet, puis appeler -sortUsingDescriptors: à chaque fois, mais même si le tableau est déjà sortingé, il faudra toujours N comparaisons.

Le cacao en lui-même ne fournit tout simplement pas une approche efficace pour maintenir une collection dans un ordre sortingé. Java a une classe TreeSet qui conserve les éléments dans l’ordre sortingé à chaque fois qu’un object est inséré ou supprimé, mais pas Cocoa. C’est précisément ce problème qui m’a amené à développer quelque chose de similaire pour mon propre usage.

Dans le cadre d’un framework de structures de données dont j’ai hérité et amélioré, j’ai créé un protocole et quelques implémentations pour les ensembles sortingés . N’importe laquelle des sous-classes concrètes maintiendra un ensemble d’objects distincts dans l’ordre sortingé. Il y a encore des améliorations à apporter – la principale étant qu’il sortinge en fonction du résultat de -compare: (que chaque object dans l’ensemble doit implémenter) et n’accepte pas encore un NSSortDescriptor. (Une solution consiste à implémenter -compare: pour comparer la propriété d’intérêt sur les objects.)

Un inconvénient possible est que ces classes ne sont (actuellement) pas des sous-classes de NS (Mutable) Set, donc si vous devez passer un NSSet, il ne sera pas commandé. (Le protocole a une méthode -set qui retourne un NSSet, qui est bien sûr non ordonné.) Je prévois de le faire rapidement, comme je l’ai fait avec les sous-classes NSMutableDictionary du framework. Les commentaires sont les bienvenus. 🙂

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

NSSet est une collection d’objects non ordonnés. Regarder les références Apple Les tableaux sont des collections ordonnées.

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

Exemple du lien:

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

 // assuming anArray is array of unsorted ssortingngs NSArray *sortedArray; // sort using a selector sortedArray = [anArray sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; // sort using a function BOOL reverseSort = NO; sortedArray = [anArray sortedArrayUsingFunction:alphabeticSort context:&reverseSort]; 

Vous ne pouvez pas sortinger NSSet, car “SortArrayUsingFunction:” définit le résultat comme NSArray … Et tous les indices supérieurs fonctionnent uniquement avec Array 🙂

 NSArray *myArray = [mySet sortedArrayUsingDescriptors:descriptors]; 

Travailler parfait, et pas besoin d’autre moyen 🙂

Depuis OS X 10.7 et iOS 5.0, il y a NSOrderedSet . Vous pouvez l’utiliser pour conserver les objects et conserver leur ordre. NSMutableOrderedSet a des méthodes de sorting. Dans certaines situations, cela peut améliorer les performances, car vous n’avez pas besoin de créer un object distinct tel que NSArray pour stocker les éléments sortingés.