Je dois vérifier si un dict a une clé ou non. Comment?
NSDictionary
contient une clé (non spécifique), vous devez utiliser [dictionary allKeys].count == 0
Si le count
est 0
il n'y a pas de clés dans le NSDictionary
.
Je dois vérifier si un dict a une clé ou non. Comment?
NSDictionary
contient une clé (non spécifique), vous devez utiliser [dictionary allKeys].count == 0
Si le count
est 0
il n'y a pas de clés dans le NSDictionary
.
Réponses:
objectForKey
retournera nil si une clé n'existe pas.
[NSNull null]
place.
if ([[dictionary allKeys] containsObject:key]) {
// contains key
}
ou
if ([dictionary objectForKey:key]) {
// contains object
}
Les versions plus récentes d'Objective-C et de Clang ont une syntaxe moderne pour cela:
if (myDictionary[myKey]) {
}
Il n'est pas nécessaire de vérifier l'égalité avec nil, car seuls les objets Objective-C non nuls peuvent être stockés dans des dictionnaires (ou des tableaux). Et tous les objets Objective-C sont des valeurs véridiques. Même @NO
, @0
et [NSNull null]
évaluez comme vrai.
Edit: Swift est maintenant une chose.
Pour Swift, vous essayez quelque chose comme le suivant
if let value = myDictionary[myKey] {
}
Cette syntaxe n'exécutera le bloc if que si myKey est dans le dict et si c'est le cas, la valeur est stockée dans la variable value. Notez que cela fonctionne même pour les valeurs de falsey comme 0.
if ([mydict objectForKey:@"mykey"]) {
// key exists.
}
else
{
// ...
}
Lors de l'utilisation de dictionnaires JSON:
#define isNull(value) value == nil || [value isKindOfClass:[NSNull class]]
if( isNull( dict[@"my_key"] ) )
{
// do stuff
}
J'aime la réponse de Fernandes même si vous demandez l'obj deux fois.
Cela devrait également faire (plus ou moins la même chose que Martin A).
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
}
Martin et cette réponse fonctionnent tous les deux sur iPad2 iOS 5.0.1 9A405
Un piège très méchant qui vient de perdre un peu de mon temps à déboguer - vous pouvez vous retrouver invité par la saisie semi-automatique à essayer d'utiliser doesContain
ce qui semble fonctionner.
Sauf, doesContain
utilise une comparaison d'id au lieu de la comparaison de hachage utilisée par objectForKey
donc si vous avez un dictionnaire avec des clés de chaîne, il retournera NON à 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
Oui. Ce type d'erreurs est très courant et entraîne un plantage de l'application. J'utilise donc pour ajouter NSDictionary dans chaque projet comme ci-dessous:
//.h code de fichier:
@interface NSDictionary (AppDictionary)
- (id)objectForKeyNotNull : (id)key;
@end
Le code de fichier //.m est comme ci-dessous
#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
Dans le code, vous pouvez utiliser comme ci-dessous:
NSStrting *testString = [dict objectForKeyNotNull:@"blah"];
Pour vérifier l'existence d'une clé dans NSDictionary:
if([dictionary objectForKey:@"Replace your key here"] != nil)
NSLog(@"Key Exists");
else
NSLog(@"Key not Exists");
Parce que rien ne peut être stocké dans les structures de données Foundation, NSNull
c'est parfois pour représenter a nil
. Parce qu'il NSNull
s'agit d'un objet singleton, vous pouvez vérifier si NSNull
la valeur est stockée dans le dictionnaire à l'aide de la comparaison directe de pointeurs:
if ((NSNull *)[user objectForKey:@"myKey"] == [NSNull null]) { }
NSNull
instance singleton a été stockée dans le dictionnaire comme valeur pour la clé @"myKey"
. C'est une chose totalement différente que la clé @"myKey"
ne soit pas dans le dictionnaire - en effet, les deux s'excluent mutuellement.
Solution pour Swift 4.2
Donc, si vous voulez simplement répondre à la question de savoir si le dictionnaire contient la clé, demandez:
let keyExists = dict[key] != nil
Si vous voulez la valeur et que vous savez que le dictionnaire contient la clé, dites:
let val = dict[key]!
Mais si, comme cela arrive habituellement, vous ne savez pas qu'elle contient la clé - vous voulez la récupérer et l'utiliser, mais seulement si elle existe - alors utilisez quelque chose comme if let
:
if let val = dict[key] {
// now val is not nil and the Optional has been unwrapped, so use it
}
Je vous suggère de stocker le résultat de la recherche dans une variable temporaire, de tester si la variable temporaire est nulle et de l'utiliser ensuite. De cette façon, vous ne regardez pas le même objet deux fois:
id obj = [dict objectForKey:@"blah"];
if (obj) {
// use obj
} else {
// Do something else
}
Comme Adirael a suggéré objectForKey
de vérifier l'existence des clés, mais lorsque vous appelez objectForKey
dans un dictionnaire annulable, l'application est bloquée, j'ai donc corrigé cela de la manière suivante.
- (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"
}