Domanda

Qual è il modo più efficace per ordinare gli oggetti in un NSSet / NSMutableSet basato su una proprietà degli oggetti del set? In questo momento il modo in cui lo faccio è scorrendo ogni oggetto, aggiungerli ad una NSMutableArray, e ordinare tale matrice con NSSortDescriptor.

È stato utile?

Soluzione

provare a utilizzare

[[mySet allObjects] sortedArrayUsingDescriptors:descriptors];

Modifica : Per iOS ≥ 4.0 e Mac OS X 10.6 ≥ è possibile utilizzare direttamente

[mySet sortedArrayUsingDescriptors:descriptors];

Altri suggerimenti

Il "modo più efficace" per ordinare un insieme di oggetti varia in base a quello che effettivamente dire. L'ipotesi casuale (che le risposte precedenti fanno) è una sorta di una volta di oggetti in un set. In questo caso, io direi che è praticamente un lancio-up tra ciò che @cobbal suggerisce e ciò che si avvicinò con - probabilmente qualcosa di simile al seguente:

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

(io dico che è un lancio-up a causa di @ cobbal approccio crea due array autoreleased, quindi la memoria raddoppia impronta. Questo è irrilevante per i piccoli insiemi di oggetti, ma tecnicamente, né l'approccio è molto efficiente.)

Tuttavia , se siete l'ordinamento degli elementi nel set più di una volta (e soprattutto se si tratta di una cosa normale) questo non è sicuramente un approccio efficiente. Si potrebbe tenere un NSMutableArray intorno e mantenerlo sincronizzato con il NSSet, quindi chiamare -sortUsingDescriptors: ogni volta, ma anche se l'array è già ordinato sarà ancora bisogno di N confronti

.

Cacao di per sé solo non fornisce un approccio efficace per il mantenimento di una collezione in modo ordinato. Java ha un TreeSet classe che mantiene gli elementi in modo ordinato ogni volta che un oggetto viene inserito o rimosso, ma Cocoa no. E 'stato proprio questo problema che ha spinto me di sviluppare qualcosa di simile per il mio uso.

Come parte di un quadro strutture di dati che ho ereditato e rinnovato, ho creato un protocollo href="http://dysart.cs.byu.edu/CHDataStructures/protocol_c_h_sorted_set-p.html" rel="noreferrer"> . Qualsiasi delle sottoclassi concrete manterrà una serie di oggetti distinti in modo ordinato. Ci sono ancora perfezionamenti da apportare - il più importante essere che smista in base al risultato di -compare: (che ogni oggetto nel set deve implementare) e non ha ancora accettare un NSSortDescriptor. (Una soluzione è quella di implementare -compare:. Per confrontare la proprietà di interesse sugli oggetti)

Una possibile svantaggio è che queste classi sono (al momento) non sottoclassi di NS (Mutevole) Set, quindi se si deve passare un NSSet, sarà non essere ordinati. (Il protocollo ha un metodo che restituisce un-set NSSet, che è ovviamente non ordinata.) Ho intenzione di rettificare che presto, come ho fatto con le sottoclassi NSMutableDictionary nel quadro. Il feedback è sicuramente il benvenuto. : -)

Per iOS ≥ 5.0 e Mac OS X 10.7 ≥ è possibile utilizzare direttamente NSOrderedSet

NSSet è una collezione di oggetti non ordinate. Vedendo mela riferimenti Gli array sono ordinate collezioni.

Guardando NSArray v'è una discussione con esempi di smistamento http://developer.apple.com/documentation/Cocoa/Conceptual/Collections/Articles/sortingFilteringArrays ...

Esempio dal 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];

Non è possibile ordinare NSSet, perché "sortedArrayUsingFunction:" set di risultati NSArray ... E tutto suggerimento superiore funziona solo con array:)

NSArray *myArray = [mySet sortedArrayUsingDescriptors:descriptors];

lavoro perfetto, e non è necessario altro modo:)

Dal momento che OS X 10.7 e iOS 5.0 c'è NSOrderedSet. Potete usarlo per tenere gli oggetti in serie e mantenere il loro ordine. NSMutableOrderedSet ha metodi per l'ordinamento. In alcune situazioni questo può dare un miglioramento delle prestazioni, dal momento che non c'è bisogno di creare l'oggetto distinto come NSArray per memorizzare elementi ordinati.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top