在嵌套的NSDictionary中查找最小值和最大值

时间:2012-12-05 07:47:35

标签: objective-c sorting nsdictionary

我有一个Person NSDictionary,其键是人的名字,对象是一个带有两个键的NSDictionary:他的昵称(NSString)和他的年龄(NSNumber)。

我想最后按照他们年龄的升序排序的人物字典,以便我可以得到最年轻和最年长的人的名字。 最好的方法是什么?

谢谢!

5 个答案:

答案 0 :(得分:4)

NSDictionary中定义了一些便捷方法,可以按值对项目进行排序,并返回已排序的键。

参见文档,

keysSortedByValueUsingComparator:
keysSortedByValueUsingSelector:
keysSortedByValueWithOptions:usingComparator:

我猜你正在使用现代的Objective-C语法,而年龄实际上表示为数字。这是它的外观:

[people keysSortedByValueUsingComparator:(NSDictionary *firstPerson, NSDictionary *secondPerson) {
    return [firstPerson[@"age"] compare:secondPerson[@"age"]];
}];

答案 1 :(得分:2)

某些语言提供已排序的词典,但标准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;
}];

答案 2 :(得分:1)

正如@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
};

答案 3 :(得分:1)

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;

答案 4 :(得分:0)

查看返回按选择器排序的键的NSDictionary's method。这种方法不止一种。您将获得一系列已排序的密钥,然后访问第一个和最后一个,并拥有您最年轻和最年长的人。