it-swarm.com.de

Was ist der effizienteste Weg, ein NSSet zu sortieren?

Was ist der effizienteste Weg, um Objekte in einem NSSet/NSMutableSet basierend auf einer Eigenschaft der Objekte in der Gruppe zu sortieren? Im Moment mache ich es durch jedes Objekt, füge sie zu einem NSMutableArray hinzu und sortiere dieses Array mit NSSortDescriptor.

63
Boon

versuchen Sie es mit

[[mySet allObjects] sortedArrayUsingDescriptors:descriptors];

Bearbeiten : Für iOS ≥ 4.0 und Mac OS X ≥ 10.6 können Sie direkt verwenden

[mySet sortedArrayUsingDescriptors:descriptors];
114
cobbal

Die "effizienteste Methode" zum Sortieren einer Objektgruppe hängt davon ab, was Sie eigentlich meinen. Die zufällige Annahme (die die vorherigen Antworten machen) ist eine einmalige Sortierung von Objekten in einem Satz. In diesem Fall würde ich sagen, es ist so ziemlich ein Wurf zwischen dem, was @cobbal vorschlägt, und dem, was Sie sich ausgedacht haben - wahrscheinlich etwas wie das Folgende:

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

(Ich sage, es ist ein Wurf, weil der Ansatz von @ cobbal zwei automatisch freigegebene Arrays erzeugt, so dass sich der Speicherbedarf verdoppelt. Dies ist für kleine Mengen von Objekten unerheblich, aber technisch gesehen ist keiner der Ansätze sehr effizient.)

Allerdings, wenn Sie die Elemente im Set mehr als einmal sortieren (und vor allem, wenn es sich um eine normale Sache handelt), ist dies definitiv kein effizienter Ansatz. Sie könnten ein NSMutableArray aufbewahren und mit dem NSSet synchronisieren. Dann -sortUsingDescriptors aufrufen: Jedes Mal, aber selbst wenn das Array bereits sortiert ist, sind noch N Vergleiche erforderlich.

Kakao allein bietet keinen effizienten Ansatz, um eine Sammlung in sortierter Reihenfolge zu verwalten. Java verfügt über eine TreeSet - Klasse, die die Elemente in sortierter Reihenfolge verwaltet, wenn ein Objekt eingefügt oder entfernt wird, Cocoa jedoch nicht. Genau dieses Problem hat mich dazu veranlasst, etwas Ähnliches für meinen eigenen Gebrauch zu entwickeln.

Als Teil eines Datenstruktur-Frameworks, das ich geerbt und umgestaltet habe, erstellte ich ein Protokoll und einige Implementierungen für sortierte Sets . In jeder der konkreten Unterklassen werden verschiedene Objekte in sortierter Reihenfolge verwaltet. Es müssen noch weitere Verfeinerungen vorgenommen werden - vor allem die Sortierung nach dem Ergebnis von -compare: (die jedes Objekt in der Gruppe implementieren muss) und akzeptiert noch keinen NSSortDescriptor. (Eine Problemumgehung besteht darin, -compare zu implementieren, um die interessierende Eigenschaft der Objekte zu vergleichen.)

Ein möglicher Nachteil ist, dass diese Klassen (derzeit) keine Unterklassen von NS (Mutable) Set sind. Wenn Sie also ein NSSet übergeben müssen, wird es nicht angeordnet. (Das Protokoll hat eine -set-Methode, die ein NSSet zurückgibt, was natürlich ungeordnet ist.) Ich habe vor, das bald zu korrigieren, wie ich es mit den Unterklassen NSMutableDictionary im Framework getan habe. Feedback ist auf jeden Fall willkommen. :-)

15
Quinn Taylor

Für iOS ≥ 5.0 und Mac OS X ≥ 10.7 können Sie NSOrderedSet direkt verwenden.

8
bioffe

NSSet ist eine Sammlung ungeordneter Objekte. Betrachten von Apple-Referenzen Arrays sind geordnete Sammlungen.

Wenn Sie sich NSArray ansehen, finden Sie eine Diskussion mit Beispielen zum Sortieren unter http://developer.Apple.com/documentation/Cocoa/Conceptual/Collections/Articles/sortingFilteringArrays ...

Beispiel aus dem Link:

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];
2
stefanB

Seit OS X 10.7 und iOS 5.0 gibt es NSOrderedSet. Sie können es verwenden, um Objekte in der richtigen Reihenfolge zu halten. NSMutableOrderedSet verfügt über Methoden zum Sortieren .. In einigen Situationen kann dies zu einer Leistungsverbesserung führen, da Sie zum Speichern sortierter Elemente kein separates Objekt wie NSArray erstellen müssen.

0
Andriy

Sie können NSSet nicht sortieren, da "sortiertesArrayUsingFunction:" das Ergebnis als NSArray ....__ festlegt.

NSArray *myArray = [mySet sortedArrayUsingDescriptors:descriptors];

Funktioniere perfekt und brauche keine andere Möglichkeit :)

0
iTux