2012-12-05 223 views
2

我有一个Person NSDictionary,其关键是人的名称,而对象是一个带有两个键的NSDictionary:他的昵称(NSString)和他的年龄(NSNumber)。在嵌套NSDictionary中查找最小值和最大值

我想结束按照他们年龄的升序排序的人字典,这样我就可以得到最年轻和最老的人的名字。 做什么是最好的方法?

谢谢!

回答

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; 
}]; 
+0

你的意思是只是手动排序呢?没有任何方便的方法可以使用自定义比较器吗? –

+0

'NSArray'有几种排序方法,但请参阅我的编辑 - 对于您的情况,最好忘记排序。 – zoul

+0

非常感谢! –

4

有一些方便的方法在NSDictionary中定义按值排序项并获取排序的键。

见文档,

keysSortedByValueUsingComparator: 
keysSortedByValueUsingSelector: 
keysSortedByValueWithOptions:usingComparator: 

我猜你正在使用的现代Objective-C的语法和年龄其实是代表数字。下面是它的外观:

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

谢谢!您的答案也有效..不幸的是,不可能将两个答案标记为已接受:) –

1

As @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 
}; 
0

看,它返回一个选择排序键NSDictionary's method。有不止一种这样的方法。你得到一排排序的密钥,然后访问第一个和最后一个,并拥有你最年轻和最老的人。

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; 
相关问题