2010-12-29 17 views
19

Tengo un NSMutableDictionary que mapea NSString a NSString (aunque los valores son NSStrings, en realidad son enteros).Ordenar un NSMutableDictionary

Por ejemplo consideran las siguientes asignaciones,

"dog" --> "4" 
"cat" --> "3" 
"turtle" --> "6" 

que me gustaría terminar con los 10 mejores entradas en el diccionario ordenados por orden del valor decreciente. ¿Alguien puede mostrarme el código para esto? Quizás haya una matriz de claves y otra matriz de valores. Sin embargo, lo es, no me importa. Solo estoy tratando de que sea eficiente.

Gracias!

Respuesta

46

Obtenga la matriz de valores, ordene esa matriz y luego obtenga la clave correspondiente al valor.

Puede obtener los valores con:

NSArray* values = [myDict allValues]; 
NSArray* sortedValues = [values sortedArrayUsingSelector:@selector(comparator)]; 

Pero, si la colección es como usted muestra en su ejemplo, (quiero decir, se puede deducir el valor de la clave), siempre se puede ordenar la en cambio, las teclas están jugando con los valores.

usando:

NSArray* sortedKeys = [myDict keysSortedByValueUsingSelector:@selector(comparator)]; 

El comparador es un selector de mensajes que se envía al objeto que desea ordenar.

Si desea pedir cadenas, debe usar un comparador NSString. Los comparadores NSString son, por ejemplo: caseInsensitiveCompare o localizedCaseInsensitiveCompare :.

Si ninguno de estos son válidos para usted, usted puede llamar a su propia función comparador

[values sortedArrayUsingFunction:comparatorFunction context:nil] 

Ser comparatorFunction (de AppleDocumentation)

NSInteger intSort(id num1, id num2, void *context) 
{ 
    int v1 = [num1 intValue]; 
    int v2 = [num2 intValue]; 
    if (v1 < v2) 
     return NSOrderedAscending; 
    else if (v1 > v2) 
     return NSOrderedDescending; 
    else 
     return NSOrderedSame; 
} 
+0

bien, así que vamos a decir que desea utilizar su segundo método. ¿Qué es exactamente "comparador"? Lo siento, nunca antes había usado este método. ¿Eso significa que necesito escribir mi propia función? ¿Cómo se vería? ¡¡Gracias!! – CodeGuy

+0

Edité la respuesta, espero que ya esté suficientemente claro – HyLian

+2

@HyLian ¿Qué pasa si NSDictionary contiene valores duplicados para claves diferentes? ¿Cómo rastreará qué clave debería recogerse? –

0
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"interest" ascending:YES]; 
[unsortedArray sortUsingDescriptors:[NSArray arrayWithObjects:descriptor,nil]]; 
recentSortedArray = [stories copy]; 
4

La forma más sencilla es:

NSArray *sortedValues = [[yourDictionary allValues] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; 
NSMutableDictionary *orderedDictionary=[[NSMutableDictionary alloc]init]; 
for(NSString *valor in sortedValues){ 
    for(NSString *clave in [yourDictionary allKeys]){ 
     if ([valor isEqualToString:[yourDictionary valueForKey:clave]]) { 
      [orderedDictionary setValue:valor forKey:clave]; 
     } 
    } 
} 
+0

Esto no es eficiente, la respuesta aceptada tiene la solución correcta. – Cutetare

3

Ordenación de las teclas y utilizarlo para rellenar una matriz con los valores:

NSArray *keys = [dict allKeys]; 
NSArray *sKeys = [keys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; 
NSMutableArray *sValues = [[[NSMutableArray alloc] init] autorelease]; 

for(id k in sKeys) { 
    id val = [dict objectForKey:k]; 
    [sValues addObject:val]; 
} 
+0

Ideal para traducir un diccionario a su equivalente de matriz ordenada, ordenada por claves. –

+0

No está ordenando el número de dos dígitos. – Rajesh

4

El uso de este método:

- (NSArray *)sortKeysByIntValue:(NSDictionary *)dictionary { 

    NSArray *sortedKeys = [dictionary keysSortedByValueUsingComparator:^NSComparisonResult(id obj1, id obj2) { 
     int v1 = [obj1 intValue]; 
     int v2 = [obj2 intValue]; 
     if (v1 < v2) 
      return NSOrderedAscending; 
     else if (v1 > v2) 
      return NSOrderedDescending; 
     else 
      return NSOrderedSame; 
    }]; 
    return sortedKeys; 
} 

Llámalo y luego crear un nuevo diccionario con claves ordenados por valor:

NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys: 
          @"4", @"dog", 
          @"3", @"cat", 
          @"6", @"turtle", 
          nil]; 

NSArray *sortedKeys = [self sortKeysByIntValue:dictionary]; 
NSMutableDictionary *sortedDictionary = [[NSMutableDictionary alloc] init]; 

for (NSString *key in sortedKeys){ 
    [sortedDictionary setObject:dictionary[key] forKey:key]; 
} 
0

si desea ordenar los datos en orden ascendente para la clave 'nombre' para tal tipo de Ejemplo, entonces esto puede ayudarlo.

arrayAnimalList = [ { 'nombre' = Perro, 'animal_id' = 001 }, { 'nombre' = Rat, 'animal_id' = 002 }, { 'nombre '= Cat, ' animal_id '= 003 } ];

Este es un código que le ayudan a obtener matriz ordenada

//here you have to pass key for which you want to sort data 

NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES]; 

    NSArray *sortDescriptors = [NSArray arrayWithObject:descriptor]; 

    // here you will get sorted array in 'sortedArray' 
    NSMutableArray * sortedArray = [[arrayAnimalList sortedArrayUsingDescriptors:sortDescriptors] mutableCopy]; 
Cuestiones relacionadas