Necesito verificar si un dict tiene una clave o no. ¿Cómo?
NSDictionarycontiene cualquier tecla (no específica) se debe utilizar [dictionary allKeys].count == 0si el countes 0que no hay llaves en el NSDictionary.
Necesito verificar si un dict tiene una clave o no. ¿Cómo?
NSDictionarycontiene cualquier tecla (no específica) se debe utilizar [dictionary allKeys].count == 0si el countes 0que no hay llaves en el NSDictionary.
Respuestas:
objectForKey devolverá nil si no existe una clave.
[NSNull null]en su lugar.
if ([[dictionary allKeys] containsObject:key]) {
// contains key
}
o
if ([dictionary objectForKey:key]) {
// contains object
}
Las versiones más recientes de Objective-C y Clang tienen una sintaxis moderna para esto:
if (myDictionary[myKey]) {
}
No es necesario verificar la igualdad con nulo, porque solo los objetos Objective-C no nulos pueden almacenarse en diccionarios (o matrices). Y todos los objetos Objective-C son valores verdaderos. Incluso @NO, @0y [NSNull null]evaluar como verdadero.
Editar: Swift ahora es una cosa.
Para Swift, probarías algo como lo siguiente
if let value = myDictionary[myKey] {
}
Esta sintaxis solo ejecutará el bloque if si myKey está en el dict y si lo está, entonces el valor se almacena en la variable de valor. Tenga en cuenta que esto funciona incluso para valores falsey como 0.
if ([mydict objectForKey:@"mykey"]) {
// key exists.
}
else
{
// ...
}
Al usar diccionarios JSON:
#define isNull(value) value == nil || [value isKindOfClass:[NSNull class]]
if( isNull( dict[@"my_key"] ) )
{
// do stuff
}
Me gusta la respuesta de Fernandes aunque pidas el obj dos veces.
Esto también debería hacer (más o menos lo mismo que Martin's 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 y esta respuesta funcionan en iPad2 iOS 5.0.1 9A405
Un problema muy desagradable que acaba de perder un poco de mi tiempo de depuración: es posible que el autocompletado te pida que intentes usar lo doesContainque parece funcionar.
Excepto, doesContainutiliza una comparación de id en lugar de la comparación de hash utilizada por objectForKeylo que si tiene un diccionario con teclas de cadena, devolverá NO a 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
Si. Este tipo de errores son muy comunes y conducen al bloqueo de la aplicación. Entonces uso para agregar NSDictionary en cada proyecto de la siguiente manera:
//.h código de archivo:
@interface NSDictionary (AppDictionary)
- (id)objectForKeyNotNull : (id)key;
@end
//.m el código del archivo es el siguiente
#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
En el código puede usar lo siguiente:
NSStrting *testString = [dict objectForKeyNotNull:@"blah"];
Para verificar la existencia de la clave en NSDictionary:
if([dictionary objectForKey:@"Replace your key here"] != nil)
NSLog(@"Key Exists");
else
NSLog(@"Key not Exists");
Debido a que nil no se puede almacenar en las estructuras de datos de Foundation, a NSNullveces se representa unnil . Debido a que NSNulles un objeto singleton, puede verificar si NSNulles el valor almacenado en el diccionario mediante la comparación de puntero directo:
if ((NSNull *)[user objectForKey:@"myKey"] == [NSNull null]) { }
NSNullinstancia de singleton se ha almacenado en el diccionario como el valor de la clave @"myKey". Eso es algo totalmente diferente a que la clave @"myKey"no esté en el diccionario; de hecho, los dos son mutuamente excluyentes.
Solución para swift 4.2
Entonces, si solo quiere responder a la pregunta de si el diccionario contiene la clave, pregunte:
let keyExists = dict[key] != nil
Si desea el valor y sabe que el diccionario contiene la clave, diga:
let val = dict[key]!
Pero si, como suele suceder, no sabe que contiene la clave, desea buscarla y usarla, pero solo si existe, use algo como if let:
if let val = dict[key] {
// now val is not nil and the Optional has been unwrapped, so use it
}
Como Adirael sugirió objectForKeyverificar la existencia de la clave, pero cuando llamas objectForKeyal diccionario anulable, la aplicación se bloquea, así que lo solucioné de la siguiente manera.
- (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"
}