¿Cómo clasifico un NSMutableArray con objetos personalizados en él?

Lo que quiero hacer parece bastante simple, pero no puedo encontrar ninguna respuesta en la web. Yo tengo un NSMutableArray de objetos, y digamos que son objetos 'Persona'. Quiero ordenar el NSMutableArray por 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 usaría Collections.sort con un comparador personalizado en línea ... ¿cómo diablos haces esto en Objective-C?

preguntado el 30 de abril de 09 a las 03:04

27 Respuestas

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 normalmente 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. Mira esto la documentación.

Bloques (¡brillante!)

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

Rendimiento

EL -compare: y los métodos basados ​​en bloques serán un poco más rápidos, en general, que usar NSSortDescriptor ya que este último se basa en KVC. La principal ventaja del NSSortDescriptor El método es que proporciona una forma 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 una NSTableView haciendo clic en la fila del encabezado.

Respondido el 12 de junio de 17 a las 15:06

El primer ejemplo tiene un error: compara la variable de instancia birthDate en un objeto con el otro objeto en sí, en lugar de su variable birthDate. - Martín Gjaldbaek

@Martin: ¡Gracias! Es curioso que nadie más se haya dado cuenta antes de que yo obtuviera 75 votos a favor. - Georg Scholly

Debido a que esta es la respuesta aceptada y, por lo tanto, probablemente la mayoría de los usuarios la consideren definitiva, podría ser útil agregar un tercer ejemplo basado en bloques para que los usuarios sepan que también existe. - jpswain

@ orange80: Lo intenté. Ya no tengo una Mac, por lo que sería bueno si pudieras ver el código. - Georg Scholly

Si usted tiene una NSMutableArray prefiero usar los metodos sortUsingDescriptors , sortUsingFunction or sortUsingSelector. En la medida en que la matriz sea mutable, generalmente no necesito una copia ordenada. - Stephan

Consulte las NSMutableArray Método sortUsingFunction:context:

Necesitará configurar un comparar función que toma dos objetos (de tipo Person, ya que estas comparando dos Person objetos) y un contexto parámetro.

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

Esta función devuelve un NSComparisonResult: Vuelve NSOrderedAscending if PersonA.birthDate < PersonB.birthDate. Volverá NSOrderedDescending if PersonA.birthDate > PersonB.birthDate. Finalmente, volverá NSOrderedSame if PersonA.birthDate == PersonB.birthDate.

Este es un pseudocódigo aproximado; Deberá desarrollar lo que significa que una fecha sea "menos", "más" o "igual" a otra fecha (como comparar segundos desde é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 quieres algo más compacto, puedes usar operadores ternarios:

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

Inlining quizás podría acelerar esto un poco, si lo hace mucho.

Respondido el 13 de junio de 16 a las 18:06

Usar sortUsingFunction: context: es probablemente la forma más c-ish y definitivamente la más ilegible. - Georg Scholly

No tiene nada de malo, pero creo que ahora hay alternativas mucho mejores. - Georg Scholly

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 Comparator abstracta de Java, que implementa comparar (Type obj1, Type obj2). - alex reynolds

Tengo la sensación de que algunos de ustedes están buscando cualquier razón para criticar esta respuesta perfectamente buena, incluso si esa crítica tiene muy poco mérito técnico. Extraño. - alex reynolds

@Yar: puede usar la solución que proporcioné en el primer párrafo o usar varios descriptores de clasificación. sortedArrayUsingDescriptors: toma una matriz de descriptores de clasificación como argumento. - Georg Scholly

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 devolver NSOrderedSame, sin embargo, en mi código pensé en 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 clasifica en orden descendente.

Respondido el 03 de junio de 13 a las 08:06

En realidad, no necesita los lanzamientos "(Score *)" allí, solo puede hacer "Score * s1 = obj1;" porque id felizmente se convertirá en cualquier cosa sin previo aviso del compilador :-) - jpswain

derecha naranja80 downcasting no requiere un lanzamiento antes de la variable débil. - el signo de verano

Debe ordenar nil vs not-nil en la parte superior o inferior de manera consistente, por lo que el retorno final predeterminado podría ser return ((!obj1 && !obj2) ? NSOrderedSame : (obj1 ? NSOrderedAscending : NSOrderedDescending)) - scott corscadden

je 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. (ejecutar el mismo código con los mismos datos) cambió el orden, no era descendente. Digamos que i hv 4 objetos en mi matriz, 3 hv mismos datos, 1 es diferente. - Nikesh K

Si realmente espera objetos que no son de la clase "Score", 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 causar problemas. Puede devolver un valor que implique que los objetos de puntuación se clasifiquen antes que todos los demás objetos y que todos los demás objetos se clasifiquen de la misma forma. - gnasher729

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 liberará automáticamente.

Respondido el 13 de junio de 16 a las 10:06

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

Esto funciona a las mil maravillas:

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

Respondido el 24 de diciembre de 16 a las 07:12

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

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 se desperdició tiempo cuando copié y pegué y falló sin la 's' en sortedArrayUsingDescriptors

Respondido 19 Abr '20, 15:04

La llamada al método es en realidad "sortedArrayUsingDescriptors:", con una 's' al final. - Filtro CI

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

Respondido el 31 de enero de 16 a las 18:01

Su Person los objetos necesitan implementar un método, digamos compare: que toma otro Person objeto y regreso NSComparisonResult según la relación entre los 2 objetos.

Entonces llamarías sortedArrayUsingSelector: con @selector(compare:) y debería estar hecho.

Hay otras formas, pero hasta donde yo sé, no existe un equivalente de cacao de la Comparable interfaz. Utilizando sortedArrayUsingSelector: es probablemente la forma más indolora de hacerlo.

Respondido 30 Abr '09, 07:04

Los bloques de iOS 4 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

Respondido 08 ago 16, 13:08

Para NSMutableArray, utilizar el sortUsingSelector método. Lo ordena en el lugar, sin crear una nueva instancia.

Respondido el 03 de junio de 13 a las 08:06

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

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

Respondido el 29 de Septiembre de 15 a las 21:09

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

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

Eso funciona porque los objetos de la matriz (NSNumber objetos) implementan el método de comparación. Podrías hacer lo mismo por NSString objetos, 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. Desde NSNumber Los objetos implementan un método de comparación, se podría reescribir de manera mucho más simple:

 #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 incluso podría destilarse hasta 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 para la versión todo en una línea.

Respondido el 03 de junio de 13 a las 08:06

Utiliza NSSortDescriptor para ordenar un NSMutableArray con objetos personalizados

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

Respondido el 14 de junio de 18 a las 10:06

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

Respondido el 11 de enero de 13 a las 11:01

por qué pasar una matriz mutable, cuando se devuelve una nueva matriz. ¿Por qué crear una envoltura? - vikingosegundo

He creado una pequeña biblioteca de métodos de categorías, llamada Linq a ObjectiveC, eso facilita este tipo de cosas. Utilizando la sort método con un selector de teclas, puede ordenar por birthDate como sigue:

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

respondido 06 mar '13, 08:03

Deberías llamarlo "LINQ a Objective-C". - Pedro Mortensen

Acabo de realizar 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

Respondido el 13 de diciembre de 14 a las 03:12

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

Respondido el 31 de enero de 16 a las 18:01

clasificación NSMutableArray es 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];

Respondido el 31 de enero de 16 a las 18:01

Ordenar usando NSComparator

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

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

Ordena con 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 utilizar para ordenar el contenido 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 que no distinga 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/

Respondido el 17 de junio de 16 a las 06:06

Los protocolos y la programación funcional de Swift lo hacen 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 de orden superior ordenada (por :) 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)

respondido 27 mar '17, 23:03

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 objetivo es,

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

respondido 28 nov., 17:14

Tienes que crear sortDescriptor y luego puedes ordenar el nsmutablearray usando 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)

Respondido 12 Abr '18, 11:04

Ordenar matriz en Swift


Para Swifty La persona a continuación es una técnica muy limpia para lograr el objetivo anterior a nivel mundial. Tengamos una clase personalizada de ejemplo de User que tienen algunos atributos.

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

Ahora tenemos una matriz que necesitamos ordenar en base a createdDate ya sea ascendente y / o descendente. Así que 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 extension of Array es User. En palabras simples, agreguemos algunos métodos solo para aquellos Array que solo tienen User objetos en él.

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)

Método anterior en extension solo será accesible si el Array es de tipo [User] || Array<User>

respondido 24 mar '18, 21:03

Ú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 to, ese objeto contiene los valores de cadena de apellido.

Respondido 24 Abr '19, 14:04

Versión Swift: 5.1

Si tiene una estructura o clase personalizada y desea ordenarlas arbitrariamente, debe llamar a sort () usando un cierre final que clasifique en un campo que especifique. A continuación, se muestra un ejemplo que utiliza una matriz de estructuras personalizadas que se clasifican en una propiedad en 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 () así:

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

Respondido 20 Feb 20, 13:02

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

respondido 16 mar '20, 13:03

La pregunta es sobre NSMutableArray, no sobre la colección de Arrays en Swift - Ricardo

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(@"===============================");

Respondido 08 Abr '14, 00:04

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.