在NSArray中检查NSDictionary密钥存在的更好选择?

时间:2010-02-15 21:03:38

标签: objective-c cocoa nsarray nsdictionary

我有NSArray的NSArray。我需要检查NSArray中NSDictionary的键是否至少出现一个对象。我是通过使用

来做到这一点的
int i;
for (i=0;i< [myArray count];i++)
{
    if ([[[myArray objectAtIndex: i] objectForKey: myKey] isEqualToString: myString]) {
        found = YES;
        break;
    } else {
        found = NO;
    }
}

但我怀疑它有更好/更快的替代方案......

由于

7 个答案:

答案 0 :(得分:7)

是。使用“快速枚举”,通常也称为for-in循环:

for (NSDictionary* dict in myArray) {

另外,要比较NSString,请使用-isEqualToString:

   if ([[dict objectForKey: myKey] isEqualToString:myString]) {

也就是说,没有算法改进(即这种方法已经是最好的了。)

答案 1 :(得分:6)

这与您使用当前数据结构获得的速度一样快。您正在为数组中的每个字典执行O(1)查找。如果你有大量的字典,这可能会变得昂贵,所以你可以考虑(很大程度上取决于你的数据的语义)保持一个单独的旁视NSSet,它包含一组包含字典中所有值的字符串对象。然后你可以在那个集合中检查一次是否存在。

告诉我们更多有关数据形式的信息,以获得更多见解......

使用== s NSString运算符也要小心。如果您确实要检查字符串的文本是否相等,则应使用-isEqualToString:代替,因为您的表单只会进行参考比较。

答案 2 :(得分:5)

您应该使用快速枚举,它将在幕后使用C数组迭代对象。现在,每次循环都会调用-objectAtIndex:和-count。

如果myKey是一个字符串,你也可以查看NSPredicate。我的直觉告诉我它会慢一些,但你永远不知道它是否会受益于NSDictionary的内部优化:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%@ LIKE %@", myKey, myString];
BOOL found = ([[myArray filteredArrayUsingPredicate:predicate] count] > 0);

答案 3 :(得分:3)

使用键值编码可以更加简洁:

[[myArray valueForKey:myKey] containsObject:myString];

它不一定更快(我怀疑它会更慢),但速度并不总是主要关注点。速度在特定情况下是否至关重要,需要进行剖析才能确定。

答案 4 :(得分:2)

使用==检查字符串相等性可能会导致意外行为,因为您实际上是在比较指针(如果您确定要处理由两个指针指向的单个字符串对象,则可能没问题) )。 isEqualToString:可能是您想要的。

您可以使用“快速枚举”来略微简化:

bool found = NO;

for (NSDictionary *dict in myArray) {
    found = [[dict objectForKey:myKey] isEqualToString:myString];

    if (found)
        break;
}

它只是“更快”,因为它写的字更少;执行速度是一样的。

答案 5 :(得分:1)

收到对象后,您可以检查收到的对象是“NSArray”,“NSDictionary”还是“NSString”等。您可以使用以下代码验证您的对象。

if([obj isKindOfClass:[NSArray class]]){
    NSLog(@"IS NSArray");
}
else if([obj isKindOfClass:[NSDictionary class]]){
    NSLog(@"Is NSDictionary");
}
else
{
    NSLog(@"Other");
}

答案 6 :(得分:0)

快速枚举

BOOL found;

for (NSDictionary *dict in array) {

        if ([[dict objectForKey:@"YOURKEY"] isEqualToString:@"YOURVALUE"]) {
            found = YES;
            break;
        } else {
            found = NO;
        }
    }