XCode: 4 formas de ordenar un NSArray


Tenemos un NSArray o un NSMutableArray que queremos ordenar. Lo primero es conocer NSComparisonResult, es un "enum" que indica si el resultado de una comparación entre dos elementos es ascendente (a < b), descendente (a > b) o ambos son iguales (a == b). Hay varias clases de uso común que la implementan (p.ej. NSString). 

Supongamos que queremos ordenar un "array" de personas por su nombre:

@interface Persona

@property NSString *nombre;

@end

// Y luego tenemos declarado
@property NSArray *personas

Hay varias formas de hacerlo:

-(NSComparisonResult)compare:

- (NSComparisonResult)compare:(Persona *)other {
  
  return [self.nombre compare:other.nombre];
}

// Y luego en otro sitio
NSArray *sortedArray;
sortedArray = [originalArray sortedArrayUsingSelector:@selector(compare:)];

NSSortDescriptor

// Y luego en otro sitio
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"nombre" ascending:YES];

NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];

NSArray *sortedArray = [personas sortedArrayUsingDescriptors:sortDescriptors];

Blocks

NSArray *sortedArray;
sortedArray = [personas sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
    NSString *nombreA = [(Persona*)a nombre];
    NSString *nombreB = [(Persona*)b nombre];
    return [nombreA compare:nombreB];
}];

sortUsingFunction:context:

Este metodo sólo es válido para NSMutableArray's, pero tiene la ventaja de que en el context le podemos enviar el parámetro que queramos (útil por ejemplo para ordenar objetos geolocalizados).

NSComparisonResult compare(Persona *a, Persona *b, void *context) {
  return [a.nombre compare:b.nombre];
}

// Y luego en otra parte
NSMutableArray *sortedArray = [NSMutableArray arrayWithArray:personas];
[sortedArray sortUsingFunction:compare context:nil];