Necesito verificar si un dict tiene una clave o no. ¿Cómo?
NSDictionary
contiene cualquier tecla (no específica) se debe utilizar [dictionary allKeys].count == 0
si el count
es 0
que no hay llaves en el NSDictionary
.
Necesito verificar si un dict tiene una clave o no. ¿Cómo?
NSDictionary
contiene cualquier tecla (no específica) se debe utilizar [dictionary allKeys].count == 0
si el count
es 0
que 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
, @0
y [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 doesContain
que parece funcionar.
Excepto, doesContain
utiliza una comparación de id en lugar de la comparación de hash utilizada por objectForKey
lo 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 NSNull
veces se representa unnil
. Debido a que NSNull
es un objeto singleton, puede verificar si NSNull
es el valor almacenado en el diccionario mediante la comparación de puntero directo:
if ((NSNull *)[user objectForKey:@"myKey"] == [NSNull null]) { }
NSNull
instancia 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ó objectForKey
verificar la existencia de la clave, pero cuando llamas objectForKey
al 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"
}