我有一个 Person NSDictionary,它的键是人的姓名,对象是一个 NSDictionary,它有两个键:他的昵称 (NSString) 和他的年龄 (NSNumber)。
我想得到按年龄升序排序的 Person 字典,这样我就可以得到最年轻和最年长的人的名字。最好的方法是什么?
谢谢!
我有一个 Person NSDictionary,它的键是人的姓名,对象是一个 NSDictionary,它有两个键:他的昵称 (NSString) 和他的年龄 (NSNumber)。
我想得到按年龄升序排序的 Person 字典,这样我就可以得到最年轻和最年长的人的名字。最好的方法是什么?
谢谢!
NSDictionary 中定义了一些方便的方法来按值对项目进行排序并取回排序后的键。
见文档,
keysSortedByValueUsingComparator:
keysSortedByValueUsingSelector:
keysSortedByValueWithOptions:usingComparator:
我猜你正在使用现代的 Objective-C 语法,而年龄实际上是用数字表示的。这是它的外观:
[people keysSortedByValueUsingComparator:(NSDictionary *firstPerson, NSDictionary *secondPerson) {
return [firstPerson[@"age"] compare:secondPerson[@"age"]];
}];
一些语言提供排序字典,但标准NSDictionary
本质上是未排序的。您可以获取所有键,对键数组进行排序,然后根据排序后的键遍历字典。(NSDictionary
有几种我不知道的用例的便捷方法,请参阅 Anurag 的回答。)
您的情况有点复杂,解决它的一种方法是引入一个临时字典,将年龄映射到名称。但是,如果您只是在最小和最大年龄之后,只需遍历所有人并跟踪最大和最小年龄和姓名:
NSString *oldestName = nil;
float maxAge = -1;
for (NSString *name in [persons allKeys]) {
NSDictionary *info = persons[name];
float age = [info[@"age"] floatValue];
if (age > maxAge) {
oldestName = info[@"nick"];
maxAge = age;
}
}
如果我们回到对字典排序的想法,这可能会奏效:
NSArray *peopleByAge = [people keysSortedByValueUsingComparator:^(id a, id b) {
// Again, see Anurag’s answer for a more concise
// solution using the compare: method on NSNumbers.
float ageA = [a objectForKey:@"age"];
float ageB = [b objectForKey:@"age"];
return (ageA > ageB) ? NSOrderedDescending
: (ageB > ageA) ? NSOrderedAscending
: NSOrderedSame;
}];
正如@Zoul 所说,标准的 NSDictionary 是未排序的。
要对其进行排序,您可以使用数组,我会这样做
//the dictionary is called dict : in my case it is loaded from a plist file
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
//make a dicoArray that is sorted so the results are sorted
NSArray *dicoArray = [[dict allKeys] sortedArrayUsingComparator:^(id firstObject, id secondObject) {
return [((NSString *)firstObject) compare:((NSString *)secondObject) options:NSNumericSearch];
}];
检查所有排序选项的帮助。在本例中,字典使用被视为数值的键进行排序(对我来说就是这种情况)。
如果您需要以另一种方式排序,则排序可能性列表是
enum {
NSCaseInsensitiveSearch = 1,
NSLiteralSearch = 2,
NSBackwardsSearch = 4,
NSAnchoredSearch = 8,
NSNumericSearch = 64,
NSDiacriticInsensitiveSearch = 128,
NSWidthInsensitiveSearch = 256,
NSForcedOrderingSearch = 512,
NSRegularExpressionSearch = 1024
};
在iOS 9.2中
// NSNumbers 字典
NSDictionary * phoneNumbersDict = @{@"400-234-090":67,@"701-080-080":150};
// 升序
NSArray * keysArraySortedByValue = [phoneNumbersDict keysSortedByValueUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
return [obj1 compare:obj2];
}];
// 降序排列
NSArray * keysArraySortedByValue = [phoneNumbersDict keysSortedByValueUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
return [obj2 compare:obj1];
}];
这是 NSComparisonResults 的枚举。
enum {
NSOrderedAscending = -1,
NSOrderedSame,
NSOrderedDescending
};
typedef NSInteger NSComparisonResult;
查看NSDictionary 的方法,该方法返回按选择器排序的键。这样的方法不止一种。你得到一组排序的键,然后访问第一个和最后一个,并拥有你最小和最年长的人。