检查NSDictionary中是否存在键

78

如何检查这是否存在?

[[dataArray objectAtIndex:indexPathSet.row] valueForKey:@"SetEntries"]

我想知道这个键是否存在,该怎么做呢?

非常感谢你 :)

编辑: dataArray中有对象。这些对象是NSDictionaries。


你为什么要使用 -valueForKey: 而不是 -objectForKey:?前者用于键值编码,比后者稍微慢一些。 - user557219
9个回答

161

我假设 [dataArray objectAtIndex:indexPathSet.row] 返回的是一个NSDictionary,那么您可以直接将valueForKey的结果与nil进行比较。

例如:

if ([[dataArray objectAtIndex:indexPathSet.row] valueForKey:@"SetEntries"] != nil) {
    // The key existed...

}
else {
    // No joy...

}

该键的值也可能为空,因此这种方法将无法完全测试字典中是否存在该键。 - Andrei A.
1
@AndreiA. 你不能将nil添加到NSDictionary中。 - John Parker

47

我知道你已经选择了一个答案,但我发现这在NSDictionary上是一个相当有用的类别。到了这个点上,你开始涉及到效率以及各种不同的答案。嗯...半斤八两...

- (BOOL)containsKey: (NSString *)key {
     BOOL retVal = 0;
     NSArray *allKeys = [self allKeys];
     retVal = [allKeys containsObject:key];
     return retVal;
}

我也在我的类别中编写了相同的方法,但是当我使用UIImageWriteToSavedPhotosAlbum()时发生了奇怪的崩溃。经过缩小范围,我将方法名称从containsKey更改为hasKey,崩溃消失了。 - kaala
这比被接受的答案好多了。我想按键搜索而不是判断键值是否为nil。你可以在字典中有一个指向nil值的键。但是该键仍然存在。被接受的答案并没有涵盖这种情况。但是这个解决方案涵盖了。 - Houman
3
关于键的值为nil并不正确:NSDictionary文档的第二段(https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/Reference/Reference.html)表明“键和值都不能为nil;如果你需要在字典中表示null值,你应该使用NSNull。”无论是这个回答还是被接受的回答都适用于你的场景,即在一个字典中,某个键的值为null(类型为NSNull)。 - Jarno Lamberg
1
或者:返回[[self allKeys] containsObject:key] ? YES : NO; - SmileBot
3
好的,@Jamo,你的提醒很好。我建议远离这个答案。我猜在底层,调用allKeys和containsObject方法都至少是O(n),而valueForKey方法可能要少得多。 - orion elenzil

34

检查是否为 nil:

if ([[dataArray objectAtIndex:indexPathSet.row] valueForKey:@"SetEntries"] != nil) {
    // SetEntries exists in this dict
} else {
    // No SetEntries in this dict
}

该键的值也可能为nil,因此这种方法无法完全测试字典中是否存在该键。 - Andrei A.
@AndreiA。在NSDictionary中,键和值都不能为nil。要表示nil,可以使用NSNull。 - Aaron Ash

9

同样可以使用Objective-C字面量进行操作,使用以下语法:

NSDictionary *dict = @{ @"key1" : @"value1", @"key2" : @"value2" };
if (dict[@"key2"])
NSLog(@"Exists");
else
NSLog(@"Does not exist");

对于Swift版本,以下代码有效。let headers:Dictionary = httpResponse.allHeaderFieldsif (headers["errorcode"] != nil) { print("error key exists ") } - Narasimha Nallamsetty

1

试试这个:

if ([dict objectForKey:@"bla"]) {
   // use obj
} else {
   // Do something else like create the object
}

2
这可能是一个技术上正确的解释,但如果您在答案正文中提供更详细的讨论来阐明您的推理,那么您将为社区提供更好的服务(并且很可能会获得更多的赞)。为什么使用objectForKey:方法是合适的?为什么不需要显式地检查值?至少,在问题中提供的代码示例将使您的示例更容易与原始问题联系起来。 - Palpatim

0

这个可以用更少的代码实现同样的功能:

if (dataArray[indexPathSet.row][@"SetEntries"] != nil) { /* the key exists */        } 
else                                                   { /* the key doesn't exist */ }

-1

使用(unsigned long)选项:

if ( (unsigned long)[[dataArray objectAtIndex:indexPathSet.row] valueForKey:@"SetEntries"] ) {
    // Key exist;
}else{
    // Key not exist;
};

将指向对象的指针转换为“unsigned long”没有任何意义。 - fishinear

-1

检查字典是否包含任何值。我更喜欢使用[dic allKeys].count > 0来进行检查。


这并没有回答问题。 - fishinear

-1
if ((NSNull *)[[dataArray objectAtIndex:indexPathSet.row] valueForKey:@"SetEntries"] != nil) {
    // SetEntries exists in this dict
} else {
    // No SetEntries in this dict
}

那就是正确的答案。


1
BOOL 转换为 NSNull* 有什么用? - NiñoScript

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接