web-dev-qa-db-fra.com

Comment vérifier si un NSDictionary ou NSMutableDictionary contient une clé?

Je dois vérifier si un dict a une clé ou non. Comment?

447

objectForKey retournera nil si une clé n'existe pas.

752
Adirael
if ([[dictionary allKeys] containsObject:key]) {
    // contains key
}

ou

if ([dictionary objectForKey:key]) {
    // contains object
}
160

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 de vérité. Même @NO, @0 et [NSNull null] sont considérés comme vrais. 

Edit: Swift est maintenant une chose. 

Pour Swift, essayez quelque chose comme ce qui suit

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 de valeur. Notez que cela fonctionne même pour les valeurs de Falsey telles que 0.

97
Andrew Hoos
if ([mydict objectForKey:@"mykey"]) {
    // key exists.
}
else
{
    // ...
}
20
ChristopheD

Lors de l'utilisation de dictionnaires JSON:

#define isNull(value) value == nil || [value isKindOfClass:[NSNull class]]

if( isNull( dict[@"my_key"] ) )
{
    // do stuff
}
9
Ratata Tata

J'aime la réponse de Fernandes même si vous demandez deux fois l'obj. 

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

8
q231950

Un casse-tête très méchant qui a juste fait perdre un peu de mon temps au débogage - vous pouvez être amené par l'auto-complétion à essayer d'utiliser doesContain qui semble fonctionner.

Excepté, doesContain utilise une comparaison d'identifiant au lieu de la comparaison de hachage utilisée par objectForKey. Ainsi, si vous avez un dictionnaire avec des clés de chaîne, il retournera NON à 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
5
Andy Dent

Oui. Ce type d'erreur est très courant et conduit à un crash de l'application. J'utilise donc pour ajouter NSDictionary à chaque projet comme ci-dessous:

code du fichier //.h:

@interface NSDictionary (AppDictionary)

- (id)objectForKeyNotNull : (id)key;

@end

//.m code du fichier 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"];
5
torap

En utilisant Swift, ce serait:

if myDic[KEY] != nil {
    // key exists
}
4
rsc

Étant donné que nil ne peut pas être stocké dans les structures de données Foundation, NSNull représente parfois une nil. Étant donné que NSNull est un objet singleton, vous pouvez vérifier si NSNull est la valeur stockée dans le dictionnaire à l'aide de la comparaison directe de pointeur:

if ((NSNull *)[user objectForKey:@"myKey"] == [NSNull null]) { }
3
Fernandes

Pour vérifier l'existence de la clé dans NSDictionary: 

if([dictionary objectForKey:@"Replace your key here"] != nil)
    NSLog(@"Key Exists");
else
    NSLog(@"Key not Exists");
3
Aamir

Je vous suggérerais de stocker le résultat de la recherche dans une variable temporaire, de vérifier si la variable temporaire est nulle et de l'utiliser. 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
}
1
Martin

Comme Adirael a suggéré à objectForKey de vérifier l’existence de clés, mais lorsque vous appelez objectForKeydans le dictionnaire nullable, l’application se bloque et j’ai corrigé le problème 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;

}

0
Aleem
if ([MyDictionary objectForKey:MyKey]) {
      // "Key Exist"
} 
0
saurabh rathod

Solution pour Swift 4.2

Donc, si vous voulez juste 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 se produit habituellement, vous ne savez pas qu'elle contient la clé - vous voulez la récupérer et l'utiliser, mais seulement si elle existe - 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
}
0
Enea Dume