在大型NSDictionary中查找最低值和相应的键

时间:2014-06-15 22:24:17

标签: ios objective-c nsarray nsdictionary

我有一个NSDictionary,NSString作为键,NSNumber作为值,如下所示

NSDictionary *dictionary = @{@"Apple" : [NSNumber numberWithInt: 6],
                             @"Banana" : [NSNumber numberWithInt: 1],
                             @"Peach" : [NSNumber numberWithInt: 14],
                             @"Lychee" : [NSNumber numberWithInt: 1]};

在这里,我想找到最低的键和值,在此示例中将是Lychee : 1Banana: 1之间的关系。对于较小的字典,我只是按照answer的建议对所有值进行排序,并根据排名检索数组中的第一个(或绑定的)对象。但是,如果NSDictionary非常,我想知道是否有办法做到这一点,我可以选择最低的键值对吗?

谢谢!

3 个答案:

答案 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;请原谅轻微错误)