Domanda

Ho bisogno di controllare se un dict ha una chiave o meno. Come?

È stato utile?

Soluzione

objectForKey restituirà nil se una chiave non esiste.

Altri suggerimenti

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

o

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

Più recenti versioni di Objective-C e Clang hanno una sintassi moderna per questo:

if (myDictionary[myKey]) {

}

Non c'è bisogno di verificare la presenza di uguaglianza con nil, perché solo non-nil oggetti Objective-C possono essere memorizzati nei dizionari (o array). E tutti gli oggetti Objective-C sono valori truthy. @NO Anche, @0, e [NSNull null] valutare come vero.

Modifica: Swift è ormai un ricordo.

Per Swift si sarebbe provare qualcosa di simile al seguente

if let value = myDictionary[myKey] {

}

Questa sintassi esegue solo il blocco if se myKey è nel dict e se è il valore viene memorizzato nella variabile valore. Si noti che questo funziona per i valori Falsey anche come 0.

if ([mydict objectForKey:@"mykey"]) {
    // key exists.
}
else
{
    // ...
}

Quando si utilizza dizionari JSON:

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

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

mi piace risposta Fernandes', anche se si chiede per l'obj due volte.

Questo dovrebbe anche fare (più o meno la stessa di 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
}

di Martin e questa risposta sia il lavoro su iPad2 iOS 5.0.1 9A405

Un molto brutto Gotcha che ha appena sprecato un po 'del mio tempo di debug -. Si possono trovare te richiesto dal completamento automatico di provare a utilizzare doesContain che sembra funzionare

Ad eccezione, doesContain utilizza un confronto id al posto del confronto hash utilizzato da objectForKey quindi se avete un dizionario con chiavi stringa tornerà NO ad un 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

Utilizzando Swift, sarebbe:

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

Sì. Questo tipo di errori sono molto comuni e portare a crash del app. Quindi io uso per aggiungere NSDictionary in ogni progetto come di seguito:

codice del file // h:.

@interface NSDictionary (AppDictionary)

- (id)objectForKeyNotNull : (id)key;

@end

//. Codice di m file è il seguente

#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

Nel codice è possibile utilizzare, come di seguito:

NSStrting *testString = [dict objectForKeyNotNull:@"blah"];

Per la verifica dell'esistenza di chiave nel NSDictionary:

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

A causa nil non può essere immagazzinato in strutture di dati Fondazione NSNull è a volte a rappresentare un nil. Perché NSNull è un oggetto Singleton è possibile controllare per vedere se NSNull è il valore memorizzato nel dizionario utilizzando confronto diretto puntatore:

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

Soluzione rapida 4.2

Quindi, se si desidera solo per rispondere alla domanda se il dizionario contiene la chiave, chiedere:

let keyExists = dict[key] != nil

Se si desidera che il valore e si conosce il dizionario contiene la chiave, dire:

let val = dict[key]!

Ma se, come di solito accade, non si sa che contiene la chiave - si vuole prenderlo e usarlo, ma solo se esiste - quindi utilizzare qualcosa come if let:

if let val = dict[key] {
    // now val is not nil and the Optional has been unwrapped, so use it
}

Io suggerirei di memorizzare il risultato della ricerca in una variabile temporanea, di prova se la variabile temperatura è pari a zero e poi usarlo. In questo modo non si guarda lo stesso oggetto due volte:

id obj = [dict objectForKey:@"blah"];

if (obj) {
   // use obj
} else {
   // Do something else
}

Come suggerito Adirael objectForKey per controllare esistenza chiave, ma quando si chiama dizionario objectForKeyin annullabile, app viene arrestato così ho riparato questo da modo seguente.

- (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"
} 
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top