Come ordinare un NSMutableArray con oggetti personalizzati in esso?


1268

Quello che voglio fare sembra abbastanza semplice, ma non riesco a trovare risposte sul web. Ho un NSMutableArrayoggetto, e diciamo che sono oggetti "Person". Voglio ordinare NSMutableArrayper Person.birthDate che è un NSDate.

Penso che abbia qualcosa a che fare con questo metodo:

NSArray *sortedArray = [drinkDetails sortedArrayUsingSelector:@selector(???)];

In Java renderei il mio oggetto implementabile Comparable, o userei Collections.sort con un comparatore personalizzato inline ... come mai lo fai in Objective-C?

Risposte:


2299

Metodo di confronto

O implementate un metodo di confronto per il vostro oggetto:

- (NSComparisonResult)compare:(Person *)otherObject {
    return [self.birthDate compare:otherObject.birthDate];
}

NSArray *sortedArray = [drinkDetails sortedArrayUsingSelector:@selector(compare:)];

NSSortDescriptor (meglio)

o di solito anche meglio:

NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"birthDate"
                                           ascending:YES];
NSArray *sortedArray = [drinkDetails sortedArrayUsingDescriptors:@[sortDescriptor]];

È possibile ordinare facilmente per più chiavi aggiungendone più di una all'array. È anche possibile utilizzare metodi di confronto personalizzati. Dai un'occhiata alla documentazione .

Blocks (lucido!)

C'è anche la possibilità di ordinare con un blocco da Mac OS X 10.6 e iOS 4:

NSArray *sortedArray;
sortedArray = [drinkDetails sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
    NSDate *first = [(Person*)a birthDate];
    NSDate *second = [(Person*)b birthDate];
    return [first compare:second];
}];

Prestazione

I -compare:metodi basati su blocco e saranno in genere un po 'più veloci, in generale, rispetto all'utilizzo NSSortDescriptorpoiché quest'ultimo si basa su KVC. Il vantaggio principale del NSSortDescriptormetodo è che fornisce un modo per definire il tuo ordinamento usando i dati, piuttosto che il codice, il che semplifica ad esempio l'impostazione delle cose in modo che gli utenti possano ordinarle NSTableViewfacendo clic sulla riga di intestazione.


66
Il primo esempio ha un bug: si confronta la variabile di istanza birthDate in un oggetto con l'altro oggetto stesso, piuttosto che la sua variabile birthDate.
Martin Gjaldbaek,

90
@Martin: grazie! Divertente che nessun altro ha notato prima che io ottenessi 75 voti per questo.
Georg Schölly,

76
Poiché questa è la risposta accettata, e quindi probabilmente considerata definitiva dalla maggior parte degli utenti, potrebbe essere utile aggiungere un terzo esempio basato su blocchi in modo che gli utenti sappiano che esiste anche.
jpswain,

6
@ orange80: l'ho provato. Non possiedo più un Mac, quindi sarebbe bello se potessi guardare il codice.
Georg Schölly,

11
Se ne hai uno NSMutableArraypreferisco usare i metodi sortUsingDescriptors, sortUsingFunctionoppure sortUsingSelector. Per quanto l'array sia mutabile, di solito non ho bisogno di una copia ordinata.
Stephan,

109

Vedi il NSMutableArraymetodosortUsingFunction:context:

Dovrai impostare una funzione di confronto che accetta due oggetti (di tipo Person, poiché stai confrontando due Personoggetti) e un parametro di contesto .

I due oggetti sono solo esempi di Person. Il terzo oggetto è una stringa, ad es. @ "BirthDate".

Questa funzione restituisce un NSComparisonResult: Restituisce NSOrderedAscendingse PersonA.birthDate< PersonB.birthDate. Restituirà NSOrderedDescendingse PersonA.birthDate> PersonB.birthDate. Infine, verrà restituito NSOrderedSamese PersonA.birthDate== PersonB.birthDate.

Questo è uno pseudocodice approssimativo; dovrai capire cosa significa che una data è "meno", "più" o "uguale" a un'altra data (come confrontare i secondi dall'epoca ecc.):

NSComparisonResult compare(Person *firstPerson, Person *secondPerson, void *context) {
  if ([firstPerson birthDate] < [secondPerson birthDate])
    return NSOrderedAscending;
  else if ([firstPerson birthDate] > [secondPerson birthDate])
    return NSOrderedDescending;
  else 
    return NSOrderedSame;
}

Se vuoi qualcosa di più compatto, puoi usare gli operatori ternari:

NSComparisonResult compare(Person *firstPerson, Person *secondPerson, void *context) {
  return ([firstPerson birthDate] < [secondPerson birthDate]) ? NSOrderedAscending : ([firstPerson birthDate] > [secondPerson birthDate]) ? NSOrderedDescending : NSOrderedSame;
}

L'allineamento potrebbe forse accelerare un po ', se lo fai molto.


9
Usando sortUsingFunction: context: è probabilmente il modo più semplice e sicuramente il più illeggibile.
Georg Schölly,

12
Non c'è nulla di veramente sbagliato in questo, ma penso che ora ci siano alternative molto migliori.
Georg Schölly,

6
Forse, ma non penso che sarebbe meno leggibile per qualcuno che proviene da un background Java che potrebbe essere alla ricerca di qualcosa di simile alla classe Comparator astratta di Java, che implementa compare (Type obj1, Type obj2).
Alex Reynolds,

5
Ho la sensazione che un paio di voi stiano cercando qualsiasi motivo per criticare questa risposta perfettamente valida, anche se quella critica ha ben poco merito tecnico. Strano.
Alex Reynolds,

1
@Yar: O puoi usare la soluzione che ho fornito nel primo paragrafo, oppure puoi usare più descrittori di ordinamento. sortArrayUsingDescriptors: accetta una matrice di descrittori di ordinamento come argomento.
Georg Schölly,

62

L'ho fatto in iOS 4 usando un blocco. Ho dovuto trasmettere gli elementi del mio array dall'id al mio tipo di classe. In questo caso era una classe chiamata Punteggio con una proprietà chiamata punti.

Inoltre, devi decidere cosa fare se gli elementi del tuo array non sono del tipo giusto, per questo esempio sono appena tornato NSOrderedSame, tuttavia nel mio codice ho considerato un'eccezione.

NSArray *sorted = [_scores sortedArrayUsingComparator:^(id obj1, id obj2){
    if ([obj1 isKindOfClass:[Score class]] && [obj2 isKindOfClass:[Score class]]) {
        Score *s1 = obj1;
        Score *s2 = obj2;

        if (s1.points > s2.points) {
            return (NSComparisonResult)NSOrderedAscending;
        } else if (s1.points < s2.points) {
            return (NSComparisonResult)NSOrderedDescending;
        }
    }

    // TODO: default is the same?
    return (NSComparisonResult)NSOrderedSame;
}];

return sorted;

PS: questo è l'ordinamento in ordine decrescente.


6
In realtà non hai bisogno dei cast "(Score *)" lì dentro, puoi semplicemente fare "Score * s1 = obj1;" perché id sarà felicemente trasmesso a tutto senza preavviso dal compilatore :-)
jpswain,

right orange80 downcastingnon richiede un cast prima della variabile debole.
giovedì,

Dovresti ordinare zero o non-zero in alto o in basso in modo coerente, quindi il ritorno di fine predefinito potrebbe esserereturn ((!obj1 && !obj2) ? NSOrderedSame : (obj1 ? NSOrderedAscending : NSOrderedDescending))
Scott Corscadden

eh Chris, ho provato questo codice, faccio un aggiornamento nel mio programma .. per la prima volta faccio il lavoro corretto, ho un output in ordine decrescente .. ma quando aggiorno (eseguo lo stesso codice con gli stessi dati) è cambiato l'ordine, non stava scendendo .. Diciamo che ho 4 oggetti nel mio array, 3 hv stessi dati, 1 è diverso.
Nikesh K,

Se in realtà ti aspetti oggetti che non appartengono alla classe "Punteggio", devi ordinarli un po 'più attentamente. Altrimenti hai una situazione in cui altro == punteggio1 <punteggio2 == altro che è incoerente e potrebbe causare problemi. È possibile restituire un valore che implica l'ordinamento degli oggetti Punteggio prima di tutti gli altri oggetti e l'ordinamento di tutti gli altri oggetti uguale l'uno rispetto all'altro.
gnasher729,

29

A partire da iOS 4 puoi anche usare i blocchi per l'ordinamento.

Per questo esempio particolare suppongo che gli oggetti nel tuo array abbiano un metodo 'position', che restituisce un NSInteger.

NSArray *arrayToSort = where ever you get the array from... ;
NSComparisonResult (^sortBlock)(id, id) = ^(id obj1, id obj2) 
{
    if ([obj1 position] > [obj2 position]) 
    { 
        return (NSComparisonResult)NSOrderedDescending;
    }
    if ([obj1 position] < [obj2 position]) 
    {
        return (NSComparisonResult)NSOrderedAscending;
    }
    return (NSComparisonResult)NSOrderedSame;
};
NSArray *sorted = [arrayToSort sortedArrayUsingComparator:sortBlock];

Nota: l'array "ordinato" verrà rilasciato automaticamente.


26

Ho provato di tutto, ma questo ha funzionato per me. In una classe ho un'altra classe denominata " crimeScene" e voglio ordinare in base a una proprietà di " crimeScene".

Funziona come un incantesimo:

NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:@"crimeScene.distance" ascending:YES];
[self.arrAnnotations sortUsingDescriptors:[NSArray arrayWithObject:sorter]];

21

C'è un passo mancante nella seconda risposta di Georg Schölly , ma allora funziona bene.

NSSortDescriptor *sortDescriptor;
sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"birthDate"
                                              ascending:YES] autorelease];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray;
sortedArray = [drinkDetails sortedArrayUsingDescriptors:sortDescriptors];

// ha aggiunto 's' perché il tempo è stato sprecato quando ho copiato e incollato e non è riuscito senza la 's' in sortArrayUsingDescriptors


La chiamata del metodo è in realtà "sortArrayUsingDescriptors:", con una 's' alla fine.
CIFilter

19
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"birthDate" ascending:YES] autorelease];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray;
sortedArray = [drinkDetails sortedArrayUsingDescriptors:sortDescriptors];

Grazie, funziona benissimo ...


17

I tuoi Personoggetti devono implementare un metodo, dire compare:che prende un altro Personoggetto e tornare in NSComparisonResultbase alla relazione tra i 2 oggetti.

Quindi chiameresti sortedArrayUsingSelector:con @selector(compare:)e dovrebbe essere fatto.

Ci sono altri modi, ma per quanto ne so non c'è Cocoa-equival Comparabledell'interfaccia. L'uso sortedArrayUsingSelector:è probabilmente il modo più indolore per farlo.


9

I blocchi di iOS 4 ti salveranno :)

featuresArray = [[unsortedFeaturesArray sortedArrayUsingComparator: ^(id a, id b)  
{
    DMSeatFeature *first = ( DMSeatFeature* ) a;
    DMSeatFeature *second = ( DMSeatFeature* ) b;

    if ( first.quality == second.quality )
        return NSOrderedSame;
    else
    {
        if ( eSeatQualityGreen  == m_seatQuality || eSeatQualityYellowGreen == m_seatQuality || eSeatQualityDefault  == m_seatQuality )
        {
            if ( first.quality < second.quality )
                return NSOrderedAscending;
            else
                return NSOrderedDescending;
        }
        else // eSeatQualityRed || eSeatQualityYellow
        {
            if ( first.quality > second.quality )
                return NSOrderedAscending;
            else
                return NSOrderedDescending;
        } 
    }
}] retain];

http://sokol8.blogspot.com/2011/04/sorting-nsarray-with-blocks.html un po 'di descrizione


8

Per NSMutableArray, utilizzare il sortUsingSelectormetodo Ordina al posto, senza creare una nuova istanza.


Solo un aggiornamento: anch'io cercavo qualcosa che ordinasse l'array mutabile, ora ci sono metodi equivalenti "sortUsing" per tutti i metodi "sortArrayUsing" a partire da iOS 7. Come ad esempio sortUsingComparator:.
jmathew,

7

È possibile utilizzare il seguente metodo generico per il proprio scopo. Dovrebbe risolvere il tuo problema.

//Called method
-(NSMutableArray*)sortArrayList:(NSMutableArray*)arrDeviceList filterKeyName:(NSString*)sortKeyName ascending:(BOOL)isAscending{
    NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:sortKeyName ascending:isAscending];
    [arrDeviceList sortUsingDescriptors:[NSArray arrayWithObject:sorter]];
    return arrDeviceList;
}

//Calling method
[self sortArrayList:arrSomeList filterKeyName:@"anything like date,name etc" ascending:YES];

6

Se stai solo ordinando un array di NSNumbers, puoi ordinarli con 1 chiamata:

[arrayToSort sortUsingSelector: @selector(compare:)];

Ciò funziona perché gli oggetti nell'array ( NSNumberoggetti) implementano il metodo di confronto. È possibile fare la stessa cosa per gli NSStringoggetti o anche per una matrice di oggetti dati personalizzati che implementano un metodo di confronto.

Ecco alcuni esempi di codice che utilizzano i blocchi comparatore. Ordina una serie di dizionari in cui ogni dizionario include un numero in una chiave "sort_key".

#define SORT_KEY @\"sort_key\"

[anArray sortUsingComparator: 
 ^(id obj1, id obj2) 
  {
  NSInteger value1 = [[obj1 objectForKey: SORT_KEY] intValue];
  NSInteger value2 = [[obj2 objectForKey: SORT_KEY] intValue];
  if (value1 > value2) 
{
  return (NSComparisonResult)NSOrderedDescending;
  }

  if (value1 < value2) 
{
  return (NSComparisonResult)NSOrderedAscending;
  }
    return (NSComparisonResult)NSOrderedSame;
 }];

Il codice in alto passa attraverso il lavoro per ottenere un valore intero per ogni chiave di ordinamento e confrontarli, come illustrazione di come farlo. Poiché gli NSNumberoggetti implementano un metodo di confronto, potrebbe essere riscritto molto più semplicemente:

 #define SORT_KEY @\"sort_key\"

[anArray sortUsingComparator: 
^(id obj1, id obj2) 
 {
  NSNumber* key1 = [obj1 objectForKey: SORT_KEY];
  NSNumber* key2 = [obj2 objectForKey: SORT_KEY];
  return [key1 compare: key2];
 }];

oppure il corpo del comparatore potrebbe persino essere distillato fino a 1 riga:

  return [[obj1 objectForKey: SORT_KEY] compare: [obj2 objectForKey: SORT_KEY]];

Tendo a preferire istruzioni semplici e molte variabili temporanee perché il codice è più facile da leggere e più facile da eseguire il debug. Il compilatore ottimizza comunque le variabili temporanee, quindi non vi è alcun vantaggio nella versione all-in-one-line.


5

Ho creato una piccola libreria di metodi di categoria, chiamata Linq a ObjectiveC , che rende questo tipo di cose più semplice. Utilizzando il metodo di ordinamento con un selettore a chiave, è possibile ordinare birthDatecome segue:

NSArray* sortedByBirthDate = [input sort:^id(id person) {
    return [person birthDate];
}]

Dovresti chiamarlo " LINQ to Objective-C ".
Peter Mortensen,

5

Ho appena fatto l'ordinamento a più livelli in base a requisiti personalizzati.

// ordina i valori

    [arrItem sortUsingComparator:^NSComparisonResult (id a, id b){

    ItemDetail * itemA = (ItemDetail*)a;
    ItemDetail* itemB =(ItemDetail*)b;

    //item price are same
    if (itemA.m_price.m_selling== itemB.m_price.m_selling) {

        NSComparisonResult result=  [itemA.m_itemName compare:itemB.m_itemName];

        //if item names are same, then monogramminginfo has to come before the non monograme item
        if (result==NSOrderedSame) {

            if (itemA.m_monogrammingInfo) {
                return NSOrderedAscending;
            }else{
                return NSOrderedDescending;
            }
        }
        return result;
    }

    //asscending order
    return itemA.m_price.m_selling > itemB.m_price.m_selling;
}];

https://sites.google.com/site/greateindiaclub/mobil-apps/ios/multilevelsortinginiosobjectivec


5

Ho usato sortUsingFunction :: in alcuni dei miei progetti:

int SortPlays(id a, id b, void* context)
{
    Play* p1 = a;
    Play* p2 = b;
    if (p1.score<p2.score) 
        return NSOrderedDescending;
    else if (p1.score>p2.score) 
        return NSOrderedAscending;
    return NSOrderedSame;
}

...
[validPlays sortUsingFunction:SortPlays context:nil];

5

Utilizzare NSSortDescriptor per ordinare un NSMutableArray con oggetti personalizzati

 NSSortDescriptor *sortingDescriptor;
 sortingDescriptor = [[NSSortDescriptor alloc] initWithKey:@"birthDate"
                                       ascending:YES];
 NSArray *sortArray = [drinkDetails sortedArrayUsingDescriptors:@[sortDescriptor]];

4
-(NSMutableArray*) sortArray:(NSMutableArray *)toBeSorted 
{
  NSArray *sortedArray;
  sortedArray = [toBeSorted sortedArrayUsingComparator:^NSComparisonResult(id a, id b) 
  {
    return [a compare:b];
 }];
 return [sortedArray mutableCopy];
}

perché passare in un array mutabile, quando viene restituito un nuovo array. perché creare un wrapper?
vikingosegundo,

3

L'ordinamento NSMutableArrayè molto semplice:

NSMutableArray *arrayToFilter =
     [[NSMutableArray arrayWithObjects:@"Photoshop",
                                       @"Flex",
                                       @"AIR",
                                       @"Flash",
                                       @"Acrobat", nil] autorelease];

NSMutableArray *productsToRemove = [[NSMutableArray array] autorelease];

for (NSString *products in arrayToFilter) {
    if (fliterText &&
        [products rangeOfString:fliterText
                        options:NSLiteralSearch|NSCaseInsensitiveSearch].length == 0)

        [productsToRemove addObject:products];
}
[arrayToFilter removeObjectsInArray:productsToRemove];

2

Ordina utilizzando NSComparator

Se vogliamo ordinare oggetti personalizzati che dobbiamo fornire NSComparator, che viene utilizzato per confrontare oggetti personalizzati. Il blocco restituisce un NSComparisonResultvalore per indicare l'ordinamento dei due oggetti. Quindi, al fine di ordinare l'intero array NSComparatorviene utilizzato nel modo seguente.

NSArray *sortedArray = [employeesArray sortedArrayUsingComparator:^NSComparisonResult(Employee *e1, Employee *e2){
    return [e1.firstname compare:e2.firstname];    
}];

Ordina usando NSSortDescriptor
Supponiamo, ad esempio, che abbiamo un array contenente istanze di una classe personalizzata, Employee ha gli attributi firstname, lastname ed age. L'esempio seguente mostra come creare un NSSortDescriptor che può essere utilizzato per ordinare i contenuti dell'array in ordine crescente in base alla chiave age.

NSSortDescriptor *ageDescriptor = [[NSSortDescriptor alloc] initWithKey:@"age" ascending:YES];
NSArray *sortDescriptors = @[ageDescriptor];
NSArray *sortedArray = [employeesArray sortedArrayUsingDescriptors:sortDescriptors];

Ordinamento mediante confronti personalizzati I
nomi sono stringhe e quando si ordinano le stringhe da presentare all'utente è necessario utilizzare sempre un confronto localizzato. Spesso si desidera anche eseguire un confronto senza distinzione tra maiuscole e minuscole. Ecco un esempio con (localizedStandardCompare :) per ordinare l'array per cognome e nome.

NSSortDescriptor *lastNameDescriptor = [[NSSortDescriptor alloc]
              initWithKey:@"lastName" ascending:YES selector:@selector(localizedStandardCompare:)];
NSSortDescriptor * firstNameDescriptor = [[NSSortDescriptor alloc]
              initWithKey:@"firstName" ascending:YES selector:@selector(localizedStandardCompare:)];
NSArray *sortDescriptors = @[lastNameDescriptor, firstNameDescriptor];
NSArray *sortedArray = [employeesArray sortedArrayUsingDescriptors:sortDescriptors];

Per riferimenti e discussioni dettagliate, consultare: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/SortDescriptors/Articles/Creating.html
http://www.ios-blog.co.uk/tutorials / Objective-C / how-to-sort-NSArray-con-custom-oggetti /


1

I protocolli e la programmazione funzionale di Swift ti rendono molto semplice, devi solo rendere la tua classe conforme al protocollo comparabile, implementare i metodi richiesti dal protocollo e quindi utilizzare la funzione di ordine superiore ordinata (per:) per creare una matrice ordinata senza bisogno di usare array mutabili a proposito.

class Person: Comparable {
    var birthDate: NSDate?
    let name: String

    init(name: String) {
        self.name = name
    }

    static func ==(lhs: Person, rhs: Person) -> Bool {
        return lhs.birthDate === rhs.birthDate || lhs.birthDate?.compare(rhs.birthDate as! Date) == .orderedSame
    }

    static func <(lhs: Person, rhs: Person) -> Bool {
        return lhs.birthDate?.compare(rhs.birthDate as! Date) == .orderedAscending
    }

    static func >(lhs: Person, rhs: Person) -> Bool {
        return lhs.birthDate?.compare(rhs.birthDate as! Date) == .orderedDescending
    }

}

let p1 = Person(name: "Sasha")
p1.birthDate = NSDate() 

let p2 = Person(name: "James")
p2.birthDate = NSDate()//he is older by miliseconds

if p1 == p2 {
    print("they are the same") //they are not
}

let persons = [p1, p2]

//sort the array based on who is older
let sortedPersons = persons.sorted(by: {$0 > $1})

//print sasha which is p1
print(persons.first?.name)
//print James which is the "older"
print(sortedPersons.first?.name)

1

Nel mio caso, utilizzo "sortArrayUsingComparator" per ordinare un array. Guarda il codice qui sotto.

contactArray = [[NSArray arrayWithArray:[contactSet allObjects]] sortedArrayUsingComparator:^NSComparisonResult(ContactListData *obj1, ContactListData *obj2) {
    NSString *obj1Str = [NSString stringWithFormat:@"%@ %@",obj1.contactName,obj1.contactSurname];
    NSString *obj2Str = [NSString stringWithFormat:@"%@ %@",obj2.contactName,obj2.contactSurname];
    return [obj1Str compare:obj2Str];
}];

Anche il mio oggetto è

@interface ContactListData : JsonData
@property(nonatomic,strong) NSString * contactName;
@property(nonatomic,strong) NSString * contactSurname;
@property(nonatomic,strong) NSString * contactPhoneNumber;
@property(nonatomic) BOOL isSelected;
@end

1

Devi creare sortDescriptor e quindi puoi ordinare nsmutablearray usando sortDescriptor come di seguito.

 let sortDescriptor = NSSortDescriptor(key: "birthDate", ascending: true, selector: #selector(NSString.compare(_:)))
 let array = NSMutableArray(array: self.aryExist.sortedArray(using: [sortDescriptor]))
 print(array)

1

Utilizzare in questo modo per oggetti nidificati,

NSSortDescriptor * sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"lastRoute.to.lastname" ascending:YES selector:@selector(caseInsensitiveCompare:)];
NSMutableArray *sortedPackages = [[NSMutableArray alloc]initWithArray:[packages sortedArrayUsingDescriptors:@[sortDescriptor]]];

lastRoute è un oggetto e quell'oggetto contiene l'oggetto to, quello all'oggetto contiene i valori della stringa del cognome.


0

Ordina matrice in Swift


Per Swiftypersona di seguito è una tecnica molto pulita per raggiungere l'obiettivo sopra per globalmente. Consente di avere una classe personalizzata di esempio Usercon alcuni attributi.

class User: NSObject {
    var id: String?
    var name: String?
    var email: String?
    var createdDate: Date?
}

Ora disponiamo di un array che dobbiamo ordinare in base createdDatea crescente o decrescente. Quindi, consente di aggiungere una funzione per il confronto delle date.

class User: NSObject {
    var id: String?
    var name: String?
    var email: String?
    var createdDate: Date?
    func checkForOrder(_ otherUser: User, _ order: ComparisonResult) -> Bool {
        if let myCreatedDate = self.createdDate, let othersCreatedDate = otherUser.createdDate {
            //This line will compare both date with the order that has been passed.
            return myCreatedDate.compare(othersCreatedDate) == order
        }
        return false
    }
}

Ora consente di avere un extensiondi Arrayper User. In parole semplici, aggiungiamo alcuni metodi solo per quegli array che contengono solo Useroggetti.

extension Array where Element: User {
    //This method only takes an order type. i.e ComparisonResult.orderedAscending
    func sortUserByDate(_ order: ComparisonResult) -> [User] {
        let sortedArray = self.sorted { (user1, user2) -> Bool in
            return user1.checkForOrder(user2, order)
        }
        return sortedArray
    }
}

Utilizzo per ordine crescente

let sortedArray = someArray.sortUserByDate(.orderedAscending)

Utilizzo per ordine decrescente

let sortedArray = someArray.sortUserByDate(.orderedAscending)

Utilizzo per lo stesso ordine

let sortedArray = someArray.sortUserByDate(.orderedSame)

Il metodo sopra descritto extensionsarà accessibile solo se Arraydi tipo [User]||Array<User>


0

Versione rapida: 5.1

Se si dispone di una struttura o classe personalizzata e si desidera ordinarle in modo arbitrario, è necessario chiamare sort () utilizzando una chiusura finale ordinata in un campo specificato. Ecco un esempio che utilizza una matrice di strutture personalizzate ordinate su una particolare proprietà:

    struct User {
        var firstName: String
    }

    var users = [
        User(firstName: "Jemima"),
        User(firstName: "Peter"),
        User(firstName: "David"),
        User(firstName: "Kelly"),
        User(firstName: "Isabella")
    ]

    users.sort {
        $0.firstName < $1.firstName
    }

Se si desidera restituire un array ordinato anziché ordinarlo in posizione, utilizzare sort () in questo modo:

    let sortedUsers = users.sorted {
        $0.firstName < $1.firstName
    }

0
  let sortedUsers = users.sorted {
    $0.firstName < $1.firstName
 }

La domanda riguarda NSMutableArray, non la collezione Arrays in Swift
Ricardo

-2
NSMutableArray *stockHoldingCompanies = [NSMutableArray arrayWithObjects:fortune1stock,fortune2stock,fortune3stock,fortune4stock,fortune5stock,fortune6stock , nil];

NSSortDescriptor *sortOrder = [NSSortDescriptor sortDescriptorWithKey:@"companyName" ascending:NO];

[stockHoldingCompanies sortUsingDescriptors:[NSArray arrayWithObject:sortOrder]];

NSEnumerator *enumerator = [stockHoldingCompanies objectEnumerator];

ForeignStockHolding *stockHoldingCompany;

NSLog(@"Fortune 6 companies sorted by Company Name");

    while (stockHoldingCompany = [enumerator nextObject]) {
        NSLog(@"===============================");
        NSLog(@"CompanyName:%@",stockHoldingCompany.companyName);
        NSLog(@"Purchase Share Price:%.2f",stockHoldingCompany.purchaseSharePrice);
        NSLog(@"Current Share Price: %.2f",stockHoldingCompany.currentSharePrice);
        NSLog(@"Number of Shares: %i",stockHoldingCompany.numberOfShares);
        NSLog(@"Cost in Dollars: %.2f",[stockHoldingCompany costInDollars]);
        NSLog(@"Value in Dollars : %.2f",[stockHoldingCompany valueInDollars]);
    }
    NSLog(@"===============================");
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.