辞書にキーがあるかどうかを確認する必要があります。どうやって?
NSDictionary
、任意のキー(非特異的)が含まれていますが、使用する必要がある[dictionary allKeys].count == 0
場合count
である0
には、キーが存在しませんNSDictionary
。
辞書にキーがあるかどうかを確認する必要があります。どうやって?
NSDictionary
、任意のキー(非特異的)が含まれていますが、使用する必要がある[dictionary allKeys].count == 0
場合count
である0
には、キーが存在しませんNSDictionary
。
回答:
objectForKey
キーが存在しない場合はnilを返します。
[NSNull null]
代わりに使用する必要があります。
if ([[dictionary allKeys] containsObject:key]) {
// contains key
}
または
if ([dictionary objectForKey:key]) {
// contains object
}
Objective-CとClangのより最近のバージョンには、このための最新の構文があります。
if (myDictionary[myKey]) {
}
辞書(または配列)に保存できるObjective-Cオブジェクトはnil以外なので、nilと等しいかどうかを確認する必要はありません。そして、すべてのObjective-Cオブジェクトは真実の値です。でも@NO
、@0
と[NSNull null]
trueと評価。
編集:スウィフトは今のものです。
Swiftの場合は、次のようなものを試してみてください
if let value = myDictionary[myKey] {
}
この構文は、myKeyがdictにあり、値がvalue変数に格納されている場合にのみifブロックを実行します。これは0のような誤った値でも機能することに注意してください。
デバッグに少し時間を費やしただけの非常に厄介な落とし穴-オートコンプリートが機能しているdoesContain
と思われるものを使用しようとするプロンプトが表示されます。
を除いて、がdoesContain
使用するハッシュ比較の代わりにID比較を使用するobjectForKey
ため、文字列キーを持つディクショナリがある場合は、にNOを返します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
はい。この種のエラーは非常に一般的であり、アプリのクラッシュにつながります。だから私は以下のように各プロジェクトに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"];
nilはFoundationデータ構造に格納できないためNSNull
、を表す場合がありnil
ます。NSNull
はシングルトンオブジェクトであるため、NSNull
直接ポインタ比較を使用して、値がディクショナリに格納されているかどうかを確認できます。
if ((NSNull *)[user objectForKey:@"myKey"] == [NSNull null]) { }
NSNull
インスタンスがディクショナリにkeyの値として格納されている場合、このチェックはtrueを返します@"myKey"
。これは、キー@"myKey"
が辞書にない場合とはまったく異なります。実際、この2つは相互に排他的です。
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
、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"
}