2012-04-30 11 views
5

Tengo un campo lleno de identificadores de un tercero. Los ids son números pero escritos en el db como una cadena.NSSortDescriptor ordenar un campo de cadena como un número con el bloque de comparación no funciona

Quiero ordenar una búsqueda ordenada por esta identificación en el valor del número entero. Así que estoy agregando este NSSortDescriptor al NSFetchRequest.

NSNumberFormatter *numFormatter = [[NSNumberFormatter alloc] init]; 
[numFormatter setNumberStyle:NSNumberFormatterDecimalStyle]; 
NSSortDescriptor *sortBy = [[NSSortDescriptor alloc] initWithKey:@"someId" ascending:YES comparator:^(id a, id b) { 
    return [[numFormatter numberFromString:a] compare:[numFormatter numberFromString:b]]; 
}]; 
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortBy]]; 

Pero obtengo resultados como el siguiente. Estos todavía están ordenados alfabéticamente como una cadena.

730275292 
73900038 
730172867 
7350727 
830138437 
835164 
837287901 
8338804 
930274 
9324376 

¿Qué no entiendo sobre el uso de este bloque de comparación?

EDIT 1 de mayo de 2012 09:20 am EST

Para probar si el bloque comparador está siendo utilizado, He intentado lo siguiente para ordenar en base a la longitud del campo.

NSSortDescriptor *sortBy = [[NSSortDescriptor alloc] initWithKey:@"fbId" ascending:YES comparator:^(id a, id b) { 
    if ([a length] < [b length]) { 
     return NSOrderedAscending; 
    } else if ([a length] > [b length]) { 
     return NSOrderedDescending; 
    } else { 
     return NSOrderedSame; 
    } 
}]; 
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortBy]]; 

¡Todavía estoy obteniendo resultados ordenados alfabéticamente! Entonces, esto me hace pensar que el bloque comparador ni siquiera se está utilizando.

716164250 
726354466 
73900038 
739600038 
7450727 
810138437 
801164 
801375346 
8213997 
+0

¿Qué devuelve numFormatter? ¿En t? ¿Cuerda? –

+0

NSNumberFormatter * numFormatter = [[NSNumberFormatter alloc] init]; [numFormatter setNumberStyle: NSNumberFormatterDecimalStyle]; –

+0

¿Ha intentado establecer un punto de interrupción en el bloque de comparación para ver si se está llamando? Si se está llamando, entonces puedes estar seguro de que es el código de bloque el que está mal. –

Respuesta

1

No uso NSFetchRequest, así que no puedo comentar sobre eso específicamente, pero parece ser algo relacionado. El código que usa en su bloque de comparación está bien. I fijó una serie de los números exactos que mostrar y luego los ordena con su código y todo salió bien:

NSArray *array = [NSArray arrayWithObjects:@"730275292", 
         @"73900038", 
         @"730172867", 
         @"7350727", 
         @"830138437", 
         @"835164", 
         @"837287901", 
         @"8338804", 
         @"930274", 
         @"9324376", nil]; 
    NSNumberFormatter *numFormatter = [[NSNumberFormatter alloc] init]; 
    [numFormatter setNumberStyle:NSNumberFormatterDecimalStyle]; 
    NSArray *sArray = [array sortedArrayUsingComparator:^(id a, id b) { 
     return [[numFormatter numberFromString:a] compare:[numFormatter numberFromString:b]]; 
    }]; 
    NSLog(@"%@",sArray); 

Cuando el código anterior se ejecuta, aparece un registro de:

(
    835164, 
    930274, 
    7350727, 
    8338804, 
    9324376, 
    73900038, 
    730172867, 
    730275292, 
    830138437, 
    837287901 
) 

I cree que este es el orden que estás buscando. Puede considerar tomar los resultados de su solicitud de búsqueda y ordenarlos en una matriz después de haberlos recibido. Dudo que importe si un arreglo hace la ordenación o la solicitud de búsqueda. Lo más probable es que no haya ganancia de rendimiento al usar una sobre la otra.

Si aún desea NSFetchRequest hacer la clasificación, es posible que haya algo que su falta con el fin de conseguir que ordenar correctamente. Honestamente, no estoy seguro ya que no lo he usado.

ACTUALIZACIÓN

buscar rápidamente a través de los documentos NSFetchRequest, he encontrado que hay algunos parámetros que afectan a la clasificación. Por ejemplo, en la documentación para el resultType da este mensaje:

Se utilizan setResultType: para establecer el tipo de instancia de objetos devueltos de ejecución de la solicitud, para los valores posibles, ver Si “NSFetchRequestResultType.” establezca el valor en NSManagedObjectIDResultType, esto va a degradar a cualquier ordenamientos son a consejos “mejores esfuerzos” si usted no incluye los valores de las propiedades en la solicitud .

Parece que el tipo de devolución puede estar afectando a su clasificación.

+1

La respuesta superior a http://stackoverflow.com/questions/4789782/nsfetchedresultscontroller-custom-sort-not-getting-called sugiere que algunos bloques comparadores objetivo-c no se pueden "compilar" en SQL y sugirieron básicamente lo que eres sugerencia. Ehh, una solución razonable, pero me gustaría obtener la respuesta real de por qué el bloque de comparación no funciona. Además, a menudo esto no es una solución, ya que podría ser importante tener los datos en un NSFetchResultsController (por ejemplo, cuando lo está utilizando en un TableView y aprovechando NSFetchedResultsControllerDelegate para las actualizaciones de la interfaz de usuario). –

+0

Bueno, acabo de actualizar la respuesta. Hice una búsqueda en 'ordenar' en NSFetchRequest y encontré que 'resultType' puede afectar la clasificación. Puede que quieras averiguar eso. Lamentablemente, utilizo SQLite directamente, en lugar de utilizar Core Data, por lo que este es el grado de mi conocimiento. –

+1

La respuesta real es exactamente lo que observó: las solicitudes de búsqueda no pueden convertir bloques de comparación en SQL, por lo que los descriptores de clasificación que dependen de esos bloques no funcionan con las solicitudes de obtención de datos principales. El enlace de documentación en esa respuesta lo explica con más detalle. –

11

Inténtelo!

[NSSortDescriptor sortDescriptorWithKey:@"name" 
ascending:YES 
selector:@selector(localizedStandardCompare:)] 
+2

Esto no ordenó el nombre si el tipo de datos de nombre era doble – coolcool1994

+0

¡Gracias! Finalmente un método que realmente funciona. – turingtested

Cuestiones relacionadas