Мне нужно проверить, есть ли у dict ключ или нет. Как?
NSDictionary
содержит какой - либо ключ (неспецифический) следуешь использовать [dictionary allKeys].count == 0
Если count
это 0
нет ключей в NSDictionary
.
Мне нужно проверить, есть ли у dict ключ или нет. Как?
NSDictionary
содержит какой - либо ключ (неспецифический) следуешь использовать [dictionary allKeys].count == 0
Если count
это 0
нет ключей в NSDictionary
.
Ответы:
objectForKey
вернет ноль, если ключ не существует.
[NSNull null]
вместо этого.
if ([[dictionary allKeys] containsObject:key]) {
// contains key
}
или
if ([dictionary objectForKey:key]) {
// contains object
}
Более поздние версии Objective-C и Clang имеют современный синтаксис для этого:
if (myDictionary[myKey]) {
}
Вам не нужно проверять равенство с nil, потому что в словарях (или массивах) могут храниться только объекты Objective C, не являющиеся nil. И все объекты Objective-C являются истинными значениями. Даже @NO
, @0
и [NSNull null]
оценить как истинное.
Изменить: Swift теперь вещь.
Для Swift вы бы попробовали что-то вроде следующего
if let value = myDictionary[myKey] {
}
Этот синтаксис будет выполнять блок if, только если myKey находится в dict, и если это так, то значение сохраняется в переменной value. Обратите внимание, что это работает даже для значений фальси, таких как 0.
if ([mydict objectForKey:@"mykey"]) {
// key exists.
}
else
{
// ...
}
При использовании словарей JSON:
#define isNull(value) value == nil || [value isKindOfClass:[NSNull class]]
if( isNull( dict[@"my_key"] ) )
{
// do stuff
}
Мне нравится ответ Фернандеса, даже если вы дважды спрашиваете об объекте.
Это также должно сделать (более или менее то же самое, что и у Мартина А).
id obj;
if ((obj=[dict objectForKey:@"blah"])) {
// use obj
} else {
// Do something else like creating the obj and add the kv pair to the dict
}
Мартин и этот ответ оба работают на iPad2 iOS 5.0.1 9A405
Одна очень неприятная ошибка, которая просто потратила немного моего времени на отладку - вы можете обнаружить, что автозаполнение предложило вам попробовать использовать, doesContain
что, похоже, работает.
Кроме того, doesContain
вместо сравнения хешей используется сравнение идентификаторов, objectForKey
поэтому если у вас есть словарь со строковыми ключами, он вернет NO в a doesContain
.
NSMutableDictionary* keysByName = [[NSMutableDictionary alloc] init];
keysByName[@"fred"] = @1;
NSString* test = @"fred";
if ([keysByName objectForKey:test] != nil)
NSLog(@"\nit works for key lookups"); // OK
else
NSLog(@"\nsod it");
if (keysByName[test] != nil)
NSLog(@"\nit works for key lookups using indexed syntax"); // OK
else
NSLog(@"\nsod it");
if ([keysByName doesContain:@"fred"])
NSLog(@"\n doesContain works literally");
else
NSLog(@"\nsod it"); // this one fails because of id comparison used by doesContain
Да. Ошибки такого рода очень распространены и приводят к сбою приложения. Поэтому я использую, чтобы добавить NSDictionary в каждом проекте, как показано ниже:
//.h код файла:
@interface NSDictionary (AppDictionary)
- (id)objectForKeyNotNull : (id)key;
@end
// код файла ниже
#import "NSDictionary+WKDictionary.h"
@implementation NSDictionary (WKDictionary)
- (id)objectForKeyNotNull:(id)key {
id object = [self objectForKey:key];
if (object == [NSNull null])
return nil;
return object;
}
@end
В коде вы можете использовать, как показано ниже:
NSStrting *testString = [dict objectForKeyNotNull:@"blah"];
Для проверки наличия ключа в NSDictionary:
if([dictionary objectForKey:@"Replace your key here"] != nil)
NSLog(@"Key Exists");
else
NSLog(@"Key not Exists");
Потому что nil не может быть сохранен в структурах данных Foundation NSNull
, иногда представляет собой nil
. Поскольку NSNull
это одноэлементный объект, вы можете проверить, NSNull
является ли значение, сохраненное в словаре, с помощью прямого сравнения указателей:
if ((NSNull *)[user objectForKey:@"myKey"] == [NSNull null]) { }
NSNull
экземпляр singleton был сохранен в словаре в качестве значения для ключа @"myKey"
. Это совершенно другая вещь, если ключ @"myKey"
отсутствует в словаре - на самом деле оба они взаимоисключающие.
Решение для swift 4.2
Итак, если вы просто хотите ответить на вопрос, содержит ли словарь ключ, спросите:
let keyExists = dict[key] != nil
Если вам нужно значение и вы знаете, что словарь содержит ключ, скажите:
let val = dict[key]!
Но если, как обычно бывает, вы не знаете, что он содержит ключ - вы хотите получить его и использовать, но только если он существует - тогда используйте что-то вроде if let
:
if let val = dict[key] {
// now val is not nil and the Optional has been unwrapped, so use it
}
Я бы посоветовал вам сохранить результат поиска во временной переменной, проверить, является ли временная переменная ноль, а затем использовать его. Таким образом, вы не увидите один и тот же объект дважды:
id obj = [dict objectForKey:@"blah"];
if (obj) {
// use obj
} else {
// Do something else
}
Как Adirael предложил objectForKey
проверить наличие ключа, но когда вы вызываете objectForKey
в обнуляемом словаре, приложение зависает, поэтому я исправил это следующим образом.
- (instancetype)initWithDictionary:(NSDictionary*)dictionary {
id object = dictionary;
if (dictionary && (object != [NSNull null])) {
self.name = [dictionary objectForKey:@"name"];
self.age = [dictionary objectForKey:@"age"];
}
return self;
}
if ([MyDictionary objectForKey:MyKey]) {
// "Key Exist"
}