我有一个NSDictionary,NSString
作为键,NSNumber
作为值,如下所示
NSDictionary *dictionary = @{@"Apple" : [NSNumber numberWithInt: 6],
@"Banana" : [NSNumber numberWithInt: 1],
@"Peach" : [NSNumber numberWithInt: 14],
@"Lychee" : [NSNumber numberWithInt: 1]};
在这里,我想找到最低的键和值,在此示例中将是Lychee : 1
和Banana: 1
之间的关系。对于较小的字典,我只是按照answer的建议对所有值进行排序,并根据排名检索数组中的第一个(或绑定的)对象。但是,如果NSDictionary
非常大,我想知道是否有办法做到这一点,我可以选择最低的键值对吗?
谢谢!
答案 0 :(得分:6)
正如@Tommy所说,除了进行线性搜索之外别无选择。对字典进行排序将强加O(n log(n))的函数,而线性搜索显然是O(n)。您需要使用以下内容:
NSDictionary *dictionary = @{@"Apple" : [NSNumber numberWithInt: 6],
@"Banana" : [NSNumber numberWithInt: 1],
@"Peach" : [NSNumber numberWithInt: 14],
@"Lychee" : [NSNumber numberWithInt: 1]};
NSString *lowestKey = nil;
int lowestValue = 0;
for (NSString *key in dictionary)
{
int value = [dictionary[key] intValue];
if (!lowestKey || value < lowestValue)
{
lowestKey = key;
lowestValue = value;
}
}
NSLog(@"Lowest: %@: %d", lowestKey, lowestValue);
答案 1 :(得分:3)
此代码有几个优点:enumerateKeysAndObjectsUsingBlock:不需要查找任何键,但直接从字典的数据结构访问键和值,避免了昂贵的查找。使用NSNumber比较操作使代码适用于大整数,小数和NSDecimalNumber。
__block NSString* lowestKey = nil;
__block NSNumber* lowestNumber = nil;
[dictionary enumerateKeysAndObjectsUsingBlock:^(id key, NSNumber* obj, BOOL *stop) {
if ([lowestNumber == nil || [obj compare:lowestNumber] == NSOrderedAscending)
{
lowestKey = key;
lowestNumber = obj;
}
}];
答案 2 :(得分:2)
如果没有结构可以避免线性搜索,那么您必须进行线性搜索。
E.g。
NSNumber *minValue = [[dictionary allValues] valueForKeyPath:@"@min.self"];
NSString *aLowestKey = [dictionary allKeysForObject:minValue][0];
实际上可能是两次这样的搜索;它可以更快地手动迭代密钥并锁定最小密钥。但它的代码是更多,稍微不透明的代码,因此请根据代码在速度与可维护性要求曲线上的位置进行选择。
(从咖啡馆输入iPhone;请原谅轻微错误)