Как проверить, есть ли NSDictionary или NSMutabledAllySasionAry, содержит ключ?
-
03-10-2019 - |
Вопрос
Мне нужно проверить, имеет ли DICT ключ или нет. Как?
Решение
objectForKey
вернет ноль, если ключ не существует.
Другие советы
if ([[dictionary allKeys] containsObject:key]) {
// contains key
}
или
if ([dictionary objectForKey:key]) {
// contains object
}
Более поздние версии Objective-C и Clang имеют современный синтаксис для этого:
if (myDictionary[myKey]) {
}
Вам не нужно проверять на равенство с Nil, потому что в словарях (или массивах) могут храниться только объекты Non-NIL Objective-C. И все объекты объекта-C являются правдивыми значениями. Четное @NO
, @0
, а также [NSNull null]
оценить как правда.
Редактировать: Swift теперь вещь.
Для Swift вы бы попробовали что-то вроде следующего
if let value = myDictionary[myKey] {
}
Этот синтаксис выполнит только IF Block, если MyKEy находится в Dict, и если оно, то значение сохраняется в вариабе значений. Обратите внимание, что это работает для даже значение falsey, как 0.
if ([mydict objectForKey:@"mykey"]) {
// key exists.
}
else
{
// ...
}
При использовании словарей JSON:
#define isNull(value) value == nil || [value isKindOfClass:[NSNull class]]
if( isNull( dict[@"my_key"] ) )
{
// do stuff
}
Я люблю ответ Фернандеса, даже если вы просите Obj дважды.
Это также должно делать (более или менее то же самое, что и Мартин А).
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
}
Мартин и этот ответ оба работы на iPad2 iOS 5.0.1 9A405
Одна очень неприятная чтачка, которая просто потратила немного отладки от отладки - вы можете узнать, что автоматически завершится, чтобы попробовать использовать doesContain
который, кажется, работает.
Кроме, doesContain
использует сравнение идентификатора вместо сравнения хеша, используемого objectForKey
так что если у вас есть словарь со строчными ключами, он вернется нет 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
Использование Swift, это было бы:
if myDic[KEY] != nil {
// key exists
}
да. Этот вид ошибок очень распространен и приводит к сбою приложения. Поэтому я использую, чтобы добавить Nsdictionary в каждом проекте, как показано ниже:
//.h Файловый код:
@interface NSDictionary (AppDictionary)
- (id)objectForKeyNotNull : (id)key;
@end
//.m Файл-код как ниже
#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
В коде вы можете использовать как ниже:
NSStrting *testString = [dict objectForKeyNotNull:@"blah"];
Для проверки наличия ключа в Nsdictionary:
if([dictionary objectForKey:@"Replace your key here"] != nil)
NSLog(@"Key Exists");
else
NSLog(@"Key not Exists");
Потому что ноль не может быть сохранена в структурах данных фундамента NSNull
иногда представляют собой nil
. Отказ Потому что NSNull
это синглтон объект, который вы можете проверить, если NSNull
Значение, хранящееся в словаре, используя сравнение прямого указателя:
if ((NSNull *)[user objectForKey:@"myKey"] == [NSNull null]) { }
Решение для Swift 4.2
Итак, если вы просто хотите ответить на вопрос, содержит ли словарь ключ, спросите:
let keyExists = dict[key] != nil
Если вы хотите значение, и вы знаете, что словарь содержит ключ, скажем:
let val = dict[key]!
Но если, как обычно происходит, вы не знаете, он содержит ключ - вы хотите получить его и использовать его, но только если он существует - тогда используйте что-то вроде if let
:
if let val = dict[key] {
// now val is not nil and the Optional has been unwrapped, so use it
}
Я бы предложил вам сохранить результат поиска в переменме TEMP, тестируйте, если переменная TEMP является NIL, а затем используйте ее. Таким образом, вы не смотрите один и тот же объект дважды:
id obj = [dict objectForKey:@"blah"];
if (obj) {
// use obj
} else {
// Do something else
}
Как предложил Адираэль objectForKey
Чтобы проверить ключевое существование, но когда вы звоните objectForKey
В Nullable словаре приложение разбивается, поэтому я исправил это из следующих способов.
- (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"
}