¿Cómo clasifico un NSMutableArray con objetos personalizados?

1268

Lo que quiero hacer parece bastante simple, pero no puedo encontrar ninguna respuesta en la web. Tengo una NSMutableArrayde objetos, y digamos que son objetos 'Persona'. Quiero ordenar NSMutableArraypor Person.birthDate, que es un NSDate.

Creo que tiene algo que ver con este método:

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

En Java, haría que mi objeto implemente Comparable, o use Collections.sort con un comparador personalizado en línea ... ¿cómo diablos haces esto en Objective-C?

rustyshelf
fuente

Respuestas:

2299

Método de comparación

O implementas un método de comparación para tu objeto:

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

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

NSSortDescriptor (mejor)

o generalmente incluso mejor:

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

Puede ordenar fácilmente por varias claves agregando más de una a la matriz. También es posible utilizar métodos de comparación personalizados. Echa un vistazo a la documentación .

Bloques (¡brillantes!)

También existe la posibilidad de ordenar con un bloque desde 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];
}];

Actuación

Los -compare:métodos basados ​​en bloques y serán bastante más rápidos, en general, que el uso, NSSortDescriptorya que este último se basa en KVC. La principal ventaja del NSSortDescriptormétodo es que proporciona una manera de definir su orden de clasificación utilizando datos, en lugar de código, lo que facilita, por ejemplo, configurar las cosas para que los usuarios puedan ordenar NSTableViewhaciendo clic en la fila del encabezado.

Georg Schölly
fuente
66
El primer ejemplo tiene un error: compara la variable de instancia birthDate en un objeto con el otro objeto, en lugar de su variable birthDate.
Martin Gjaldbaek
90
@ Martin: ¡Gracias! Es curioso que nadie más se haya dado cuenta antes de recibir 75 votos a favor.
Georg Schölly
76
Debido a que esta es la respuesta aceptada y, por lo tanto, probablemente considerada definitiva por la mayoría de los usuarios, podría ser útil agregar un tercer ejemplo basado en bloques para que los usuarios sepan que también existe.
jpswain
66
@ orange80: lo intenté. Ya no tengo una Mac, por lo que sería bueno si pudieras ver el código.
Georg Schölly
11
Si tienes un NSMutableArrayprefiero usar los métodos sortUsingDescriptors, sortUsingFunctiono sortUsingSelector. En la medida en que la matriz sea mutable, generalmente no necesito una copia ordenada.
Stephan
109

Ver el NSMutableArraymétodosortUsingFunction:context:

Deberá configurar una función de comparación que tome dos objetos (de tipo Person, ya que está comparando dos Personobjetos) y un parámetro de contexto .

Los dos objetos son solo instancias de Person. El tercer objeto es una cadena, por ejemplo, @ "birthDate".

Esta función devuelve un NSComparisonResult: Devuelve NSOrderedAscendingsi PersonA.birthDate< PersonB.birthDate. Volverá NSOrderedDescendingsi PersonA.birthDate> PersonB.birthDate. Finalmente, regresará NSOrderedSamesi PersonA.birthDate== PersonB.birthDate.

Este es un seudocódigo aproximado; necesitará desarrollar lo que significa que una fecha sea "menos", "más" o "igual" a otra fecha (como comparar segundos desde la época, etc.):

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;
}

Si desea algo más compacto, puede usar operadores ternarios:

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

La alineación podría acelerar esto un poco, si haces esto mucho.

Alex Reynolds
fuente
99
Usando sortUsingFunction: context: es probablemente la forma más c-ish y definitivamente la más ilegible.
Georg Schölly el
12
No tiene nada de malo, pero creo que ahora hay alternativas mucho mejores.
Georg Schölly el
66
Quizás, pero no creo que sea menos legible para alguien con experiencia en Java que podría estar buscando algo similar a la clase Comparador abstracto de Java, que implementa compare (Type obj1, Type obj2).
Alex Reynolds el
55
Tengo la sensación de que un par de ustedes está buscando alguna razón para criticar esta respuesta perfectamente buena, incluso si esa crítica tiene muy poco mérito técnico. Extraño.
Alex Reynolds
1
@Yar: Puede usar la solución que proporcioné en el primer párrafo, o puede usar varios descriptores de clasificación. sortedArrayUsingDescriptors: toma una matriz de descriptores de clasificación como argumento.
Georg Schölly
62

Hice esto en iOS 4 usando un bloque. Tuve que convertir los elementos de mi matriz de id a mi tipo de clase. En este caso, era una clase llamada Score con una propiedad llamada puntos.

También debe decidir qué hacer si los elementos de su matriz no son del tipo correcto, para este ejemplo acabo de regresar NSOrderedSame, sin embargo, en mi código, aunque hice una excepción.

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;

PD: Esto se ordena en orden descendente.

Chris
fuente
66
En realidad no necesitas los lanzamientos de "(Puntuación *)" allí, solo puedes hacer "Puntuación * s1 = obj1;" porque el id se lanzará a cualquier cosa sin previo aviso del compilador :-)
jpswain 02 de
right orange80 downcastingno requiere un lanzamiento antes de la variable débil.
thesummersign
Debería ordenar nil vs. not-nil en la parte superior o inferior de manera consistente, por lo que el retorno final predeterminado podría serreturn ((!obj1 && !obj2) ? NSOrderedSame : (obj1 ? NSOrderedAscending : NSOrderedDescending))
Scott Corscadden
heh Chris, probé este código, realizo una actualización en mi programa ... por primera vez hago el trabajo correcto, obtuve una salida de orden descendente ... pero cuando actualizo (ejecuta el mismo código con los mismos datos) cambió el orden, no descendía. Digamos que hv 4 objetos en mi matriz, 3 hv mismos datos, 1 es diferente.
Nikesh K
Si realmente espera objetos que no pertenecen a la clase "Puntuación", debe ordenarlos con un poco más de cuidado. De lo contrario, tiene una situación en la que otro == puntaje1 <puntaje2 == otro que es inconsistente y podría generar problemas. Puede devolver un valor que implique que los objetos de Puntuación se ordenen antes que todos los demás objetos, y que todos los demás objetos se ordenen entre sí.
gnasher729
29

A partir de iOS 4, también puede usar bloques para ordenar.

Para este ejemplo en particular, supongo que los objetos en su matriz tienen un método de 'posición', que devuelve 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: la matriz "ordenada" se lanzará automáticamente.

leviatán
fuente
26

Lo intenté todo, pero esto funcionó para mí. En una clase tengo otra clase llamada " crimeScene", y quiero ordenar por una propiedad de " crimeScene".

Esto funciona como un encanto:

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

Falta un paso en la segunda respuesta de Georg Schölly , pero funciona bien entonces.

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

// agregué la 's' porque perdí el tiempo cuando copié y pegué y falló sin la 's' en sortedArrayUsingDescriptors

Manuel Spuhler
fuente
La llamada al método es en realidad "sortedArrayUsingDescriptors:", con una 's' al final.
CIFilter
19
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"birthDate" ascending:YES] autorelease];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray;
sortedArray = [drinkDetails sortedArrayUsingDescriptors:sortDescriptors];

Gracias, está funcionando bien ...

Hardik Darji
fuente
17

Sus Personobjetos necesitan implementar un método, digamos compare:cuál toma otro Personobjeto, y regresar de NSComparisonResultacuerdo con la relación entre los 2 objetos.

De allí tendría que llamar sortedArrayUsingSelector:con @selector(compare:)y que se debe hacer.

Hay otras formas, pero que yo sepa, no hay Cocoa-equiv de la Comparableinterfaz. Usar sortedArrayUsingSelector:es probablemente la forma más indolora de hacerlo.

espacio libre
fuente
9

iOS 4 bloques te salvarán :)

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 poco de descripción

Kostiantyn Sokolinskyi
fuente
8

Para NSMutableArray, use el sortUsingSelectormétodo. Ordena el lugar, sin crear una nueva instancia.

DenTheMan
fuente
Solo una actualización: yo también estaba buscando algo que ordenara la matriz mutable en su lugar, ahora hay métodos equivalentes "sortUsing" para todos los métodos "sortedArrayUsing" a partir de iOS 7. Como sortUsingComparator:.
jmathew
7

Puede usar el siguiente método genérico para su propósito. Debería resolver tu 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];
MD Aslam Ansari
fuente
6

Si solo está ordenando una matriz de NSNumbers, puede ordenarlos con 1 llamada:

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

Eso funciona porque los objetos en la matriz ( NSNumberobjetos) implementan el método de comparación. Podría hacer lo mismo para los NSStringobjetos, o incluso para una matriz de objetos de datos personalizados que implementan un método de comparación.

Aquí hay un código de ejemplo que usa bloques comparadores. Ordena una serie de diccionarios donde cada diccionario incluye un número en una clave "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;
 }];

El código anterior pasa por el trabajo de obtener un valor entero para cada clave de clasificación y compararlos, como una ilustración de cómo hacerlo. Como los NSNumberobjetos implementan un método de comparación, podría reescribirse mucho más simplemente:

 #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];
 }];

o el cuerpo del comparador podría incluso ser destilado a 1 línea:

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

Tiendo a preferir declaraciones simples y muchas variables temporales porque el código es más fácil de leer y más fácil de depurar. El compilador optimiza las variables temporales de todos modos, por lo que no hay ninguna ventaja en la versión todo en una línea.

Dinesh_
fuente
5

He creado una pequeña biblioteca de métodos de categoría, llamada Linq para ObjectiveC , que hace que este tipo de cosas sea más fácil. Usando el método de clasificación con un selector de teclas, puede ordenar de la birthDatesiguiente manera:

NSArray* sortedByBirthDate = [input sort:^id(id person) {
    return [person birthDate];
}]
ColinE
fuente
Debería llamarlo " LINQ to Objective-C ".
Peter Mortensen
5

Acabo de hacer una clasificación de varios niveles según los requisitos personalizados.

// ordenar los valores

    [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

Boobalan
fuente
5

He usado sortUsingFunction :: en algunos de mis proyectos:

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];
roocell
fuente
5

Utiliza NSSortDescriptor para ordenar un NSMutableArray con objetos personalizados

 NSSortDescriptor *sortingDescriptor;
 sortingDescriptor = [[NSSortDescriptor alloc] initWithKey:@"birthDate"
                                       ascending:YES];
 NSArray *sortArray = [drinkDetails sortedArrayUsingDescriptors:@[sortDescriptor]];
Arvind Patel
fuente
4
-(NSMutableArray*) sortArray:(NSMutableArray *)toBeSorted 
{
  NSArray *sortedArray;
  sortedArray = [toBeSorted sortedArrayUsingComparator:^NSComparisonResult(id a, id b) 
  {
    return [a compare:b];
 }];
 return [sortedArray mutableCopy];
}
Emile Khattar
fuente
por qué pasar en una matriz mutable, cuando se devuelve una nueva matriz. ¿Por qué crear un envoltorio?
vikingosegundo
3

La clasificación NSMutableArrayes muy simple:

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];
Mohit
fuente
2

Ordenar usando NSComparator

Si queremos ordenar objetos personalizados, necesitamos proporcionar NSComparator, que se utiliza para comparar objetos personalizados. El bloque devuelve un NSComparisonResultvalor para denotar el orden de los dos objetos. Entonces, para ordenar toda la matriz NSComparatorse usa de la siguiente manera.

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

Ordenaciones utilizando NSSortDescriptor
Supongamos, como ejemplo, que tenemos una matriz que contiene instancias de una clase personalizada, Empleado tiene atributos nombre, apellido y edad. El siguiente ejemplo ilustra cómo crear un NSSortDescriptor que se puede usar para ordenar los contenidos de la matriz en orden ascendente por la clave de edad.

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

Ordenar usando comparaciones personalizadas Los
nombres son cadenas, y cuando ordena cadenas para presentarlas al usuario, siempre debe usar una comparación localizada. A menudo, también desea realizar una comparación entre mayúsculas y minúsculas. Aquí viene un ejemplo con (localizedStandardCompare :) para ordenar la matriz por apellido y nombre.

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

Para referencia y discusión detallada, consulte: 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-with-custom-objects /

Aamir
fuente
1

Los protocolos y la programación funcional de Swift hacen que sea muy fácil, solo tiene que hacer que su clase se ajuste al protocolo Comparable, implementar los métodos requeridos por el protocolo y luego usar la función ordenada (por:) de orden superior para crear una matriz ordenada sin necesidad de usar matrices mutables por cierto.

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)
James Rochabrun
fuente
1

En mi caso, uso "sortedArrayUsingComparator" para ordenar una matriz. Mira el siguiente código.

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];
}];

También mi objeto es,

@interface ContactListData : JsonData
@property(nonatomic,strong) NSString * contactName;
@property(nonatomic,strong) NSString * contactSurname;
@property(nonatomic,strong) NSString * contactPhoneNumber;
@property(nonatomic) BOOL isSelected;
@end
Emre Gürses
fuente
1

Debe crear sortDescriptor y luego puede ordenar nsmutablearray utilizando sortDescriptor como se muestra a continuación.

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

Úselo así para objetos anidados,

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

lastRoute es un objeto y ese objeto contiene el objeto a, que al objeto contiene los valores de cadena de apellido.

Sureshkumar Linganathan
fuente
0

Ordenar matriz en Swift


Para la Swiftypersona a continuación, es una técnica muy limpia para lograr el objetivo por encima de todo el mundo. Tengamos una clase personalizada de ejemplo de la Usercual tienen algunos atributos.

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

Ahora tenemos una matriz que debemos clasificar en función de createdDateascendente y / o descendente. Entonces, agreguemos una función para la comparación de fechas.

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
    }
}

Ahora tengamos un extensionde Arraypara User. En palabras simples, agreguemos algunos métodos solo para aquellos Array que solo tienen Userobjetos.

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
    }
}

Uso para orden ascendente

let sortedArray = someArray.sortUserByDate(.orderedAscending)

Uso para orden descendente

let sortedArray = someArray.sortUserByDate(.orderedAscending)

Uso para el mismo pedido

let sortedArray = someArray.sortUserByDate(.orderedSame)

El método anterior extensionsolo será accesible si Arrayes del tipo [User]||Array<User>

Syed Qamar Abbas
fuente
0

Versión rápida: 5.1

Si tiene una estructura o clase personalizada y desea ordenarlas arbitrariamente, debe llamar a sort () utilizando un cierre final que se clasifica en un campo que especifique. Aquí hay un ejemplo usando una matriz de estructuras personalizadas que se clasifican en una propiedad particular:

    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
    }

Si desea devolver una matriz ordenada en lugar de ordenarla en su lugar, use sorted () de esta manera:

    let sortedUsers = users.sorted {
        $0.firstName < $1.firstName
    }
sDev
fuente
0
  let sortedUsers = users.sorted {
    $0.firstName < $1.firstName
 }
manishkumar
fuente
La pregunta es sobre NSMutableArray, no sobre la colección de matrices en 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(@"===============================");
Siddhesh Bondre
fuente