辞書に鍵があるかどうかを確認する必要があります。どうやって?
キーが存在しない場合、objectForKey
はnilを返します。
if ([[dictionary allKeys] containsObject:key]) {
// contains key
}
または
if ([dictionary objectForKey:key]) {
// contains object
}
Objective-CとClangの最近のバージョンには、これに関する最新の構文があります。
if (myDictionary[myKey]) {
}
Nilと等しいかどうかをチェックする必要はありません。辞書(または配列)に格納できるのは、nil以外のObjective-Cオブジェクトだけです。そして、すべてのObjective-Cオブジェクトは真の値です。 @NO
、@0
、および[NSNull null]
でさえもtrueと評価されます。
編集:Swiftは今のものです。
Swiftの場合は、次のようにします。
if let value = myDictionary[myKey] {
}
MyKeyが辞書にあり、それが値である場合、この構文はifブロックを実行するだけです。これは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を2回要求しても、Fernandesの回答が気に入っています。
これはまたするべきである(多かれ少なかれマーティンの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'sとこの答えはどちらもiPad2 iOS 5.0.1 9A405で動作します
ちょっと厄介な問題の1つは、私のデバッグ時間を少し浪費しただけです - doesContain
を使用して試してみるようにオートコンプリートで促されることがあるかもしれません。
例外として、doesContain
はobjectForKey
によって使用されるハッシュ比較の代わりにid比較を使用するので、文字列キーを持つ辞書がある場合はdoesContain
にNOを返します。
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
はい。この種のエラーは非常に一般的であり、アプリのクラッシュにつながります。だから私は以下のように各プロジェクトに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"];
Swiftを使うと、次のようになります。
if myDic[KEY] != nil {
// key exists
}
NilはFoundationのデータ構造に格納できないため、NSNull
はnil
を表すことがあります。 NSNull
はシングルトンオブジェクトなので、直接ポインタ比較を使用して、NSNull
が辞書に格納されている値かどうかを確認できます。
if ((NSNull *)[user objectForKey:@"myKey"] == [NSNull null]) { }
NSDictionary内のキーの存在を確認するために:
if([dictionary objectForKey:@"Replace your key here"] != nil)
NSLog(@"Key Exists");
else
NSLog(@"Key not Exists");
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
}
AdiraelがobjectForKey
にキーの存在をチェックするように勧めましたが、objectForKey
in null許容辞書を呼び出すとアプリがクラッシュするので、次の方法でこれを修正しました。
- (instancetype)initWithDictionary:(NSDictionary*)dictionary {
id object = dictionary;
if (dictionary && (object != [NSNull null])) {
self.name = [dictionary objectForKey:@"name"];
self.age = [dictionary objectForKey:@"age"];
}
return self;
}
ルックアップの結果を一時変数に格納し、一時変数がnilかどうかをテストしてから使用することをお勧めします。そのようにあなたは二度同じオブジェクトを見ないでください:
id obj = [dict objectForKey:@"blah"];
if (obj) {
// use obj
} else {
// Do something else
}
if ([MyDictionary objectForKey:MyKey]) {
// "Key Exist"
}