2012-06-26 21 views
7

He visto muchos ejemplos de ordenar un diccionario por claves, y luego obtener los valores, pero ¿cómo puedo ordenar por valores?ordena las claves de NSDictionary por valor de diccionario en un NSArray

p. Ej.

{ 
blue:12; 
red:50; 
white:44; 
} 

me gustaría que éstos ordenados por número de descender a:

{ 
red:50; 
white:44; 
blue:12 
} 

Intenté conseguir un NSArray ordenada de teclas desde el cual podía creado el NSArray pedido pero el resultado todavía parece no ordenada.

NSArray* sortedKeys = [stats keysSortedByValueUsingComparator:^(id first, id second) { 

    if (first < second) { 
     return (NSComparisonResult)NSOrderedAscending; 
    } else if (first > second) { 
     return (NSComparisonResult)NSOrderedDescending; 
    } else { 
     return (NSComparisonResult)NSOrderedSame; 
    } 

    }]; 

Respuesta

9

Conceptualmente, un NSDictionary no está ordenado, como ya dijo C0deH4cker.

Si necesita una orden, puede escribir las claves en una matriz (pero puede tener problemas con la matriz reteniéndola después de que se eliminó la clave del diccionario, pero hay tutoriales sobre cómo crear una un-retaining array by using the CFArray) o NSSortedSet.

O puede la subclase NSDictionary, no muy trivial, ya que NSDictionary es un clúster de clase. Pero afortunadamente Matt muestra en su fantástico blogpost "OrderedDictionary: Subclassing a Cocoa class cluster" cómo usar un pequeño truco, una relación cubierta tiene una relación.


Tenga en cuenta, que su código

NSArray* sortedKeys = [stats keysSortedByValueUsingComparator:^(id first, id second) { 

    if (first < second) { 
     return (NSComparisonResult)NSOrderedAscending; 
    } else if (first > second) { 
     return (NSComparisonResult)NSOrderedDescending; 
    } else { 
     return (NSComparisonResult)NSOrderedSame; 
    } 

    }]; 

suele hacer, lo que quiere que haga, ya que está solicitando C-operadores a los objetos. Ahora sus punteros serán ordenados.

que debería ser algo así como

NSArray* sortedKeys = [stats keysSortedByValueUsingComparator:^(id first, id second) { 
    return [first compare:second]; 
    }]; 

o si desea solicitar el escalares, que son las envolturas como objetos (es decir NSNumber)

NSArray* sortedKeys = [stats keysSortedByValueUsingComparator:^(id first, id second) { 
    if ([first integerValue] > [second integerValue]) 
     return (NSComparisonResult)NSOrderedDescending; 

    if ([first integerValue] < [second integerValue]) 
     return (NSComparisonResult)NSOrderedAscending; 
    return (NSComparisonResult)NSOrderedSame; 
}]; 
0

Diccionarios por definición son desordenados. Se accede a ellos usando tablas hash para mayor velocidad. La única forma en que podrá "ordenar" es elegir un tipo de datos diferente. El tipo de datos de bast depende de tu intención.

+0

Me gustaría transformar los datos en un nsarray ordenado como salida, pero estoy empezando con el nsdiccionario – MonkeyBonkey

0

o usted podría ordenar sus llaves NSString directamente como:

NSArray* sortedKeys = [sortedKeys sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) { 
     NSNumber *A = @([obj1 LongValue]); 
     NSNumber *B = @([obj2 LongValue]); 

     return [A compare:B]; 
    } ]; 
Cuestiones relacionadas