获取按其各自值排序的 NSDictionary 键

Posted

技术标签:

【中文标题】获取按其各自值排序的 NSDictionary 键【英文标题】:Getting NSDictionary keys sorted by their respective values 【发布时间】:2012-03-14 19:23:31 【问题描述】:

我有一个带有整数值的NSMutableDictionary,我想得到一个键数组,按它们各自的值升序排序。例如,使用这本字典:

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

我想以数组 ["D", "A", "C", "B"] 结尾。当然,我真正的字典远不止四项。

【问题讨论】:

有几十个元素,我想要一个新的Keys数组,按包含整数的keys的升序值排序 乔希,对于我正在尝试做的事情,是的,它们都是整数。感谢大家的帮助! 【参考方案1】:

NSDictionary 方法 keysSortedByValueUsingComparator: 应该可以解决问题。

您只需要一个返回 NSComparisonResult 的方法来比较对象的值。

你的字典是

NSMutableDictionary * myDict;

你的数组是

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;
];

只需使用NSNumber 对象而不是数字常量。

顺便说一句,这取自: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Collections/Articles/Dictionaries.html

【讨论】:

Richard 的建议比我的更优雅,因为 NSNumber 已经带有合适的比较功能,但我的可能更通用。 在大多数情况下,这个解决方案可以正常工作,但我的回答是能够支持其他响应-compare:的类型 这将返回键列表,无论如何可以直接获取字典,而不是数组中的排序键列表 @Mr.G,没有办法,因为 NSDictionary 和 NSMutableDiction 没有排序。您不能对它们进行排序并期望它们在之后进行排序。【参考方案2】:

NSDictionary 有一个称为allKeys 的简洁方法。

如果您希望对数组进行排序,keysSortedByValueUsingComparator: 应该可以解决问题。

Richard 的解决方案也有效,但会进行一些您不一定需要的额外调用:

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

【讨论】:

我编辑了我的问题,我认为这是暗示键必须按键值排序 我在请求排序方面的帮助。 keysSortedByValueUsingComparator: 将执行此排序。 你能像我在问题中那样写一个简单的比较器块来升序整数吗?我是块和块结构的新手。 我相信您至少可以 try 使用该方法(文档已链接)。如果您遇到问题,请返回您的编码尝试,我很乐意为您提供帮助。【参考方案3】:

这里有一个解决方案:

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

【讨论】:

仅对以字母开头的字符串正常工作,但是当有一个以数字 10 开头的字符串时,它介于以“A”开头的第一个字符串和以“A”开头的第三个字符串之间 检查上面的答案,它更直观,更简洁,即使这样做是一样的。【参考方案4】:

最简单的解决方案:

[dictionary keysSortedByValueUsingSelector:@selector(compare:)]

【讨论】:

如何编写比较函数 请解释比较方法。 对于现有类型(例如 NSString),该方法已经存在。对于您自己创建的任何内容,该方法应根据顺序返回 NSOrderedAscending、NSOrderedSame 或 NSOrderedDescending。有关更多信息,请参阅compare:options:range: 的文档。【参考方案5】:

我在这里做了这样的事情:

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];

【讨论】:

以上是关于获取按其各自值排序的 NSDictionary 键的主要内容,如果未能解决你的问题,请参考以下文章

按值然后键对字典进行排序

从 NSDictionary 获取包含 NSNumber 布尔值的键列表,其中值为 @YES

打印按其键排序的字典项目[重复]

在 NSDictionary 中获取值

值/对象的 NSDictionary 键? [复制]

NSDictionary 按字母顺序排序[重复]