Cambiar el orden de clasificación de - [NSArray sortedArrayUsingComparator:]

I need to generate a sorted array of NSNumbers from another NSArray. Quiero usar el sortedArrayUsingComparator: method. I found this example in the Apple documentation:

NSArray *sortedArray = [array sortedArrayUsingComparator: ^(id obj1, id obj2) {
    if ([obj1 integerValue] > [obj2 integerValue]) {
        return (NSComparisonResult)NSOrderedDescending;
    }

    if ([obj1 integerValue] < [obj2 integerValue]) {
        return (NSComparisonResult)NSOrderedAscending;
    }

    return (NSComparisonResult)NSOrderedSame;
}];

Here I am just providing the comparator in a block, which is fine. The sort itself -- the bit that's hidden from me, which uses this block -- appears to be ascending.

I'd like to know if I can request a different sort order external to this block, or do I just need to flip the < y >'s (o NSOrderedXXX's) around?

preguntado el 08 de noviembre de 11 a las 17:11

5 Respuestas

If you want to sort descending, then just flip the comparisons (or flip the NSComparisonResults). There's no need to bloat the API by having an ascending: parameter when you can control that in the block directly.

respondido 08 nov., 11:22

De la documentación para -sortedArrayUsingComparator: :

"Returns an array that lists the receiving array’s elements in ascending order, as determined by the comparison method specified by a given NSComparator Block."

So You'd have to resort to using

- (NSArray *)sortedArrayUsingDescriptors:(NSArray *)sortDescriptors

but of course that means rolling your own NSSortDescriptor objects first, which may suit your purposes just fine.

respondido 08 nov., 11:22

+1 for pointing out that this is, in fact, documented. Cheers Jeff. - Tim

You can flip the operators around.

The "bit that's hidden from you" doesn't care about ascending or descending, as it doesn't know anything about your objects. It's like asking your co-worker if a hockey puck is greater or less than a muskrat. The internal implementation just uses a sorting algorithm (which is probably determined using the size of your array) and uses your block function to compare two objects.

respondido 08 nov., 11:22

Just change the logic:

NSArray *sortedArray = [array sortedArrayUsingComparator: ^(id obj1, id obj2) {

 if ([obj1 integerValue] > [obj2 integerValue]) {
      return (NSComparisonResult)NSOrderedAscending;
 }

 if ([obj1 integerValue] < [obj2 integerValue]) {
      return (NSComparisonResult)NSOrderedDescending;
 }
 return (NSComparisonResult)NSOrderedSame;
}];

For clarity it might be best to make this a method with a name similar to: decendingSort.

respondido 08 nov., 11:23

Of course this is fine, but unless you decorate it with orange-traffic-cone comments written in red-Jesus-Christ-ink stating that you've flipped the order around, at some point later this could be a potential debugging nightmare. Building a sort descriptor would make more sense and be self-commenting unless the performance would take a serious hit. - Dios de las galletas

@God A sort descriptor sounds great, please provide an implementation example for comparison. - zaph

As a side note, you are able to get the reversed order of an array using this

[[NSArray reverseObjectEnumerator] allObjects];

Fuente: https://stackoverflow.com/a/586529/1382210

contestado el 23 de mayo de 17 a las 15:05

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