Preciso verificar se um ditado tem uma chave ou não. Quão?
NSDictionary
contém qualquer (não-específica) chave que você deve usar [dictionary allKeys].count == 0
Se o count
é 0
não há chaves no NSDictionary
.
Preciso verificar se um ditado tem uma chave ou não. Quão?
NSDictionary
contém qualquer (não-específica) chave que você deve usar [dictionary allKeys].count == 0
Se o count
é 0
não há chaves no NSDictionary
.
Respostas:
objectForKey
retornará nulo se uma chave não existir.
[NSNull null]
lugar.
if ([[dictionary allKeys] containsObject:key]) {
// contains key
}
ou
if ([dictionary objectForKey:key]) {
// contains object
}
Versões mais recentes do Objective-C e Clang têm uma sintaxe moderna para isso:
if (myDictionary[myKey]) {
}
Você não precisa verificar a igualdade com zero, porque apenas objetos Objective-C diferentes de zero podem ser armazenados em dicionários (ou matrizes). E todos os objetos Objective-C são valores verdadeiros. Mesmo @NO
, @0
e [NSNull null]
avaliar como verdadeiro.
Edit: Swift agora é uma coisa.
Para Swift, você tentaria algo como o seguinte
if let value = myDictionary[myKey] {
}
Essa sintaxe somente executará o bloco if se myKey estiver no comando e se estiver, o valor será armazenado na variável value. Observe que isso funciona para valores até falsey como 0.
if ([mydict objectForKey:@"mykey"]) {
// key exists.
}
else
{
// ...
}
Ao usar dicionários JSON:
#define isNull(value) value == nil || [value isKindOfClass:[NSNull class]]
if( isNull( dict[@"my_key"] ) )
{
// do stuff
}
Gosto da resposta de Fernandes, mesmo que você peça o objeto duas vezes.
Isso também deve ser feito (mais ou menos o mesmo que o A de Martin).
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
}
A resposta de Martin e esta resposta funcionam no iPad2 iOS 5.0.1 9A405
Uma pegadinha muito desagradável que desperdiçou um pouco do meu tempo depurando - você pode ser solicitado pelo preenchimento automático a tentar usar doesContain
que parece funcionar.
Exceto, doesContain
usa uma comparação de id em vez da comparação de hash usada por objectForKey
isso, se você tiver um dicionário com chaves de string, ele retornará 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
Sim. Esse tipo de erro é muito comum e leva à falha do aplicativo. Então, eu uso para adicionar NSDictionary em cada projeto, como abaixo:
//.h código do arquivo:
@interface NSDictionary (AppDictionary)
- (id)objectForKeyNotNull : (id)key;
@end
//.m código do arquivo é como abaixo
#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
No código você pode usar como abaixo:
NSStrting *testString = [dict objectForKeyNotNull:@"blah"];
Para verificar a existência da chave no NSDictionary:
if([dictionary objectForKey:@"Replace your key here"] != nil)
NSLog(@"Key Exists");
else
NSLog(@"Key not Exists");
Como nulo não pode ser armazenado nas estruturas de dados do Foundation, NSNull
algumas vezes, representa a nil
. Como NSNull
é um objeto singleton, você pode verificar se NSNull
é o valor armazenado no dicionário usando a comparação direta de ponteiros:
if ((NSNull *)[user objectForKey:@"myKey"] == [NSNull null]) { }
NSNull
instância singleton tiver sido armazenada no dicionário como o valor da chave @"myKey"
. Isso é uma coisa totalmente diferente da chave @"myKey"
não estar no dicionário - na verdade as duas são mutuamente exclusivas.
Solução para swift 4.2
Portanto, se você quiser apenas responder à pergunta se o dicionário contém a chave, pergunte:
let keyExists = dict[key] != nil
Se você deseja o valor e sabe que o dicionário contém a chave, diga:
let val = dict[key]!
Mas se, como geralmente acontece, você não sabe que ela contém a chave - você deseja buscá-la e usá-la, mas apenas se ela existir -, 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 sugeriu objectForKey
verificar a existência de chaves, mas quando você chama um objectForKey
dicionário anulável, o aplicativo fica travado, então eu o corrigi da seguinte maneira.
- (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"
}