objective c - how - ¿Cuál es la forma más eficiente de ordenar un NSSet?
arreglos en xcode (6)
Desde OS X 10.7 e iOS 5.0, hay NSOrderedSet
. Puede usarlo para mantener los objetos en conjunto y mantener su orden. NSMutableOrderedSet
tiene métodos para ordenar. En algunas situaciones, esto puede mejorar el rendimiento, ya que no tiene que crear un objeto separado como NSArray
para almacenar elementos ordenados.
¿Cuál es la forma más eficiente de ordenar objetos en un NSSet
/ NSMutableSet
basado en una propiedad de los objetos en el conjunto? En este momento, la forma en que lo hago es iterando a través de cada objeto, agréguelos a NSMutableArray
y NSMutableArray
esa matriz con NSSortDescriptor
.
La "forma más eficiente" de ordenar un conjunto de objetos varía según lo que realmente quiere decir. La suposición casual (que hacen las respuestas anteriores) es una especie de objetos de una sola vez en un conjunto. En este caso, diría que es una mezcla entre lo que sugiere @cobbal y lo que se te ocurrió, probablemente algo como lo siguiente:
NSMutableArray* array = [NSMutableArray arrayWithCapacity:[set count]];
for (id anObject in set)
[array addObject:anObject];
[array sortUsingDescriptors:descriptors];
(Digo que es un lanzamiento porque el enfoque de @ cobbal crea dos matrices autorreleasadas, por lo que la huella de memoria se duplica. Esto no tiene importancia para pequeños conjuntos de objetos, pero técnicamente ninguno de los enfoques es muy eficiente).
Sin embargo , si está ordenando los elementos en el conjunto más de una vez (y especialmente si es algo normal) definitivamente no es un enfoque eficiente. Puede mantener un NSMutableArray alrededor y mantenerlo sincronizado con el NSSet, luego llame a -sortUsingDescriptors: cada vez, pero incluso si el array ya está ordenado, aún necesitará N comparaciones.
El cacao por sí solo no proporciona un enfoque eficiente para mantener una colección ordenada. Java tiene una clase TreeSet que mantiene los elementos ordenados cada vez que se inserta o elimina un objeto, pero Cocoa no lo hace. Fue precisamente este problema el que me impulsó a desarrollar algo similar para mi propio uso.
Como parte de un marco de estructuras de datos que heredé y renové, creé un protocolo y algunas implementaciones para conjuntos ordenados . Cualquiera de las subclases concretas mantendrá un conjunto de objetos distintos en orden ordenado. Todavía hay mejoras que deben hacerse, la más importante es que se basa en el resultado de -compare: (que cada objeto en el conjunto debe implementar) y aún no acepta un NSSortDescriptor. (Una solución alternativa es implementar -compare: para comparar la propiedad de interés en los objetos).
Una posible desventaja es que estas clases (actualmente) no son subclases de NS (Mutable) Set, por lo que si debe pasar un NSSet, no se ordenará. (El protocolo tiene un método -set que devuelve un NSSet, que por supuesto no está ordenado). Planeo rectificarlo pronto, como lo hice con las subclases NSMutableDictionary en el marco. La retroalimentación es definitivamente bienvenida. :-)
NSSet es una colección de objetos desordenados. Mirando las referencias de manzana Las matrices son colecciones ordenadas.
Mirando NSArray hay una discusión con ejemplos de clasificación en http://developer.apple.com/documentation/Cocoa/Conceptual/Collections/Articles/sortingFilteringArrays ...
Ejemplo del enlace:
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];
No se puede ordenar NSSet, porque "sortedArrayUsingFunction:" establece el resultado como NSArray ... Y todas las sugerencias superiores funcionan solo con Array :)
NSArray *myArray = [mySet sortedArrayUsingDescriptors:descriptors];
Trabaja perfecto, y no necesita otra forma :)
Para iOS ≥ 5.0 y Mac OS X ≥ 10.7 puede usar directamente NSOrderedSet
intenta usar
[[mySet allObjects] sortedArrayUsingDescriptors:descriptors];
Editar : para iOS ≥ 4.0 y Mac OS X ≥ 10.6 puede usar directamente
[mySet sortedArrayUsingDescriptors:descriptors];