iphone objective-c ios cocoa-touch nssortdescriptor

iphone - Ordenar los valores de NSString como si NSInteger utilizara NSSortDescriptor



objective-c ios (7)

Necesita comparar sus cadenas con la opción NSNumericSearch :

NSNumericSearch
Los números dentro de cadenas se comparan usando un valor numérico, es decir, Name2.txt < Name7.txt < Name25.txt .

que requiere la compare:options: método que se llamará para la comparación.

Para hacer eso, su descriptor de clasificación puede usar un Bloque NSComparator :

[NSSortDescriptor sortDescriptorWithKey:@"self" ascending:YES comparator:^(NSString * string1, NSString * string2){ return [string1 compare:string2 options:NSNumericSearch]; }];

O, de hecho, puede omitir el descriptor de clasificación y simplemente ordenar la matriz directamente , usando el mismo Bloque:

[unsortedList sortedArrayUsingComparator:^NSComparisonResult (NSString * string1, NSString * string2){ return [string1 compare:string2 options:NSNumericSearch]; }];

Creé un descriptor de ordenación para ordenar una respuesta concreta proveniente de mi servidor. Esto funciona bien con la clave de clasificación con valores hasta 9. Con más de 10 elementos, veo resultados abruptos con la tecla ordenar ordenada en el orden = 1, 10, 11, 2, 3, 4, 5, 6, 7, 8, 9

NSSortDescriptor *aSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"sort" ascending:YES]; self.myList = [NSMutableArray arrayWithArray:[unsortedList sortedArrayUsingDescriptors:[NSArray arrayWithObject:aSortDescriptor]]];

¿Cómo hacer que se organice en el orden correcto de 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11?


Puede hacerlo implementando un bloque comparador personalizado al crear su NSSortDescriptor :

NSSortDescriptor *aSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"sort" ascending:YES comparator:^(id obj1, id obj2) { if ([obj1 integerValue] > [obj2 integerValue]) { return (NSComparisonResult)NSOrderedDescending; } if ([obj1 integerValue] < [obj2 integerValue]) { return (NSComparisonResult)NSOrderedAscending; } return (NSComparisonResult)NSOrderedSame; }]; self.myList = [NSMutableArray arrayWithArray:[unsortedList sortedArrayUsingDescriptors:[NSArray arrayWithObject:aSortDescriptor]]];

Ver la documentación de Apple here


Todos los métodos anteriores necesitan un buen conocimiento de los principios básicos para implementar; pero para los novatos sugiero la forma más simple: usar el método del bloque nativo

NSArray* sortedArr =[fetchResults sortedArrayUsingComparator:^NSComparisonResult(id a, id b) { int aValue = [[a valueForKey:@"subgroupId"] intValue]; int bValue = [[b valueForKey:@"subgroupId"] intValue]; return aValue > bValue; }];


entrada

{ "seats": [{ "seatNumber": "1" }, { "seatNumber": "10" }, { "seatNumber": "2" }] }

ordenar utilizando [NSSortDescriptor sortDescriptorWithKey: @ "seatNumber" ascendente: YES selector: @selector (localizedStandardCompare :)]]. La clave es usar localizedStandardCompare. Esto resolverá tu problema.

NSArray *seats = [self.seats sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"seatNumber" ascending:YES selector:@selector(localizedStandardCompare:)]]];

salida

{ "seats": [{ "seatNumber": "1" }, { "seatNumber": "2" }, { "seatNumber": "10" }] }

documentación: https://developer.apple.com/documentation/foundation/nsstring/1409742-localizedstandardcompare


[list sortUsingSelector:@selector(localizedStandardCompare:)]; ordenará la lista de una manera "humana" (así que "11" vendrá el último, no entre "1" y "2"). Pero si realmente quieres tratar estas cadenas como números, primero debes hacer que se numeren.


NSMutableArray *list = [NSMutableArray arrayWithObjects:@"11",@"2",@"3",@"1", nil]; [list sortUsingComparator:^NSComparisonResult(id obj1, id obj2) { NSInteger firstInteger = [obj1 integerValue]; NSInteger secondInteger = [obj2 integerValue]; if( firstInteger > secondInteger) return NSOrderedDescending; if( firstInteger == secondInteger) return NSOrderedSame; return NSOrderedAscending; // edited }];

Sin garantías de rendimiento


NSSortDescriptor *aSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"sort.intValue" ascending:YES]; self.myList = [NSMutableArray arrayWithArray:[unsortedList sortedArrayUsingDescriptors:[NSArray arrayWithObject:aSortDescriptor]]];

Ordenar basado en el valor del entero.