Wat is de meest efficiënte manier om een ​​NSSet te sorteren?

Wat is de meest efficiënte manier om objecten in een NSSet/NSMutableSette sorteren op basis van een eigenschap van de objecten in de set? Op dit moment doe ik het door elk object te doorlopen, ze toe te voegen aan een NSMutableArrayen die array te sorteren met NSSortDescriptor.


Antwoord 1, autoriteit 100%

probeer het te gebruiken

[[mySet allObjects] sortedArrayUsingDescriptors:descriptors];

Bewerken: voor iOS ≥ 4.0 en Mac OS X ≥ 10.6 die u rechtstreeks kunt gebruiken

[mySet sortedArrayUsingDescriptors:descriptors];

Antwoord 2, autoriteit 13%

De ‘meest efficiënte manier’ om een ​​reeks objecten te sorteren, hangt af van wat u werkelijk bedoelt. De terloopse veronderstelling (die de vorige antwoorden maken) is een eenmalig soort objecten in een set. In dit geval zou ik zeggen dat het nogal een gooi is tussen wat @cobbalsuggereert en wat je hebt bedacht — waarschijnlijk zoiets als het volgende:

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

(Ik zeg dat het een gooi is omdat de aanpak van @cobbal twee automatisch vrijgegeven arrays creëert, dus de geheugenvoetafdruk verdubbelt. Dit is niet van belang voor kleine sets objecten, maar technisch gezien is geen van beide benaderingen erg efficiënt.)

Echter, als je de elementen in de set meer dan eens sorteert (en vooral als het een normaal iets is), is dit zeker geen efficiënte aanpak. U kunt een NSMutableArray in de buurt houden en deze gesynchroniseerd houden met de NSSet, en vervolgens -sortUsingDescriptors aanroepen: elke keer, maar zelfs als de array al is gesorteerd, heeft deze nog steeds N-vergelijkingen nodig.

Cacao op zich is gewoon geen efficiënte aanpak om een ​​collectie in gesorteerde volgorde te houden. Java heeft een klasse TreeSetdie de elementen onderhoudt in gesorteerde volgorde wanneer een object wordt ingevoegd of verwijderd, maar Cocoa niet. Het was precies dit probleem dat me ertoe bracht iets soortgelijks te ontwikkelen voor mijn eigen gebruik.

Als onderdeel van een datastructuren-framework dat ik heb geërfd en vernieuwd, heb ik een protocol gemaakt en een paar implementaties voor gesorteerde sets. Elk van de concrete subklassen zal een reeks afzonderlijke objecten in gesorteerde volgorde behouden. Er moeten nog verbeteringen worden aangebracht – de belangrijkste is dat het sorteert op basis van het resultaat van -compare: (wat elk object in de set moet implementeren) en nog geen NSSortDescriptor accepteert. (Een tijdelijke oplossing is om -compare te implementeren: om de eigenschap van belang op de objecten te vergelijken.)

Een mogelijk nadeel is dat deze klassen (momenteel) geen subklassen zijn van NS(Mutable)Set, dus als je een NSSet moet doorgeven, wordt deze niet besteld. (Het protocol heeft wel een -set-methode die een NSSet retourneert, wat natuurlijk ongeordend is.) Ik ben van plan dat binnenkort recht te zetten, zoals ik heb gedaan met de NSMutableDictionary-subklassen in het raamwerk. Feedback is zeker welkom. 🙂


Antwoord 3, autoriteit 7%

Voor iOS ≥ 5.0 en Mac OS X ≥ 10.7 kunt u rechtstreeks NSOrderedSet

gebruiken


Antwoord 4, autoriteit 2%

NSSet is een verzameling ongeordende objecten. Apple-referenties bekijken Arrays zijn geordende collecties.

Kijkend naar NSArray is er een discussie met voorbeelden van sorteren op
http://developer.apple.com/documentation/Cocoa/Conceptual/Collections/Articles/sortingFilteringArrays …

Voorbeeld van de 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];

Antwoord 5

U kunt NSSet niet sorteren, omdat “sortedArrayUsingFunction:” het resultaat instelt als NSArray…
En alle bovenste hints werken alleen met Array 🙂

NSArray *myArray = [mySet sortedArrayUsingDescriptors:descriptors];

Werkt perfect en hoeft niet anders 🙂


Antwoord 6

Sinds OS X 10.7 en iOS 5.0 is er NSOrderedSet. U kunt het gebruiken om objecten op hun plaats te houden en hun volgorde te behouden. NSMutableOrderedSetheeft sorteermethoden.
In sommige situaties kan dit een prestatieverbetering opleveren, aangezien u geen apart object zoals NSArrayhoeft te maken om gesorteerde items op te slaan.

Other episodes