web-dev-qa-db-fra.com

Obtenir les clés NSDictionary triées selon leurs valeurs respectives

J'ai un NSMutableDictionary avec des valeurs entières, et j'aimerais obtenir un tableau des clés, triées par ordre croissant selon leurs valeurs respectives. Par exemple, avec ce dictionnaire:

mutableDict = {
    "A" = 2,
    "B" = 4,
    "C" = 3,
    "D" = 1,
}

Je voudrais finir avec le tableau ["D", "A", "C", "B"]. Mon vrai dictionnaire est bien plus grand que quatre éléments, bien sûr.

42
Eric

La méthode NSDictionarykeysSortedByValueUsingComparator: devrait faire l'affaire.

Vous avez juste besoin d'une méthode renvoyant un NSComparisonResult qui compare les valeurs de l'objet.

Votre dictionnaire est

NSMutableDictionary * myDict;

Et votre tableau est

NSArray *myArray;

myArray = [myDict keysSortedByValueUsingComparator: ^(id obj1, id obj2) {

     if ([obj1 integerValue] > [obj2 integerValue]) {

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

          return (NSComparisonResult)NSOrderedAscending;
     }

     return (NSComparisonResult)NSOrderedSame;
}];

Utilisez simplement les objets NSNumber au lieu des constantes numériques.

BTW, cela provient de: https://developer.Apple.com/library/content/documentation/Cocoa/Conceptual/Collections/Articles/Dictionaries.html

66
Hermann Klecker

NSDictionary a cette méthode soignée appelée allKeys.

Si vous souhaitez que le tableau soit trié, keysSortedByValueUsingComparator: devrait faire l'affaire.

La solution de Richard fonctionne également mais effectue des appels supplémentaires dont vous n'avez pas nécessairement besoin:

// Assuming myDictionary was previously populated with NSNumber values.
NSArray *orderedKeys = [myDictionary keysSortedByValueUsingComparator:^NSComparisonResult(id obj1, id obj2){
    return [obj1 compare:obj2];
}];
27
user1040049

Voici une solution:

NSDictionary *dictionary; // initialize dictionary
NSArray *sorted = [[dictionary allKeys] sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    return [[dictionary objectForKey:obj1] compare:[dictionary objectForKey:obj2]];
}];
14

La solution la plus simple:

[dictionary keysSortedByValueUsingSelector:@selector(compare:)]

14
Rudolf Adamkovič

Ici, j'ai fait quelque chose comme ça:

NSMutableArray * weekDays = [[NSMutableArray alloc] initWithObjects:@"Sunday",@"Monday",@"Tuesday",@"Wednesday",@"Thursday",@"Friday",@"Saturday", nil];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
NSMutableArray *dictArray = [[NSMutableArray alloc] init];

for(int i = 0; i < [weekDays count]; i++)
{
    dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:i],@"WeekDay",[weekDays objectAtIndex:i],@"Name",nil];
    [dictArray addObject:dict];
}
NSLog(@"Before Sorting : %@",dictArray);

@try
{
    //for using NSSortDescriptor
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"WeekDay" ascending:YES];
    NSArray *descriptor = @[sortDescriptor];
    NSArray *sortedArray = [dictArray sortedArrayUsingDescriptors:descriptor];
    NSLog(@"After Sorting : %@",sortedArray);

    //for using predicate
    //here i want to sort the value against weekday but only for WeekDay<=5
   int count=5;
    NSPredicate *Predicate = [NSPredicate predicateWithFormat:@"WeekDay <=%d",count];
    NSArray *results = [dictArray filteredArrayUsingPredicate:Predicate];

    NSLog(@"After Sorting using predicate : %@",results);
}
@catch (NSException *exception)
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Sorting cant be done because of some error" message:[NSString stringWithFormat:@"%@",exception] delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
    [alert setTag:500];
    [alert show];
    [alert release];
}
2
tapash