Tôi cần kiểm tra xem một dict có khóa hay không. Làm sao?
NSDictionary
có chứa khóa nào không (không cụ thể) bạn nên sử dụng [dictionary allKeys].count == 0
Nếucount
là 0
không có phím trong NSDictionary
.
Tôi cần kiểm tra xem một dict có khóa hay không. Làm sao?
NSDictionary
có chứa khóa nào không (không cụ thể) bạn nên sử dụng [dictionary allKeys].count == 0
Nếucount
là 0
không có phím trong NSDictionary
.
Câu trả lời:
objectForKey
sẽ trả về nil nếu khóa không tồn tại.
[NSNull null]
thay thế.
if ([[dictionary allKeys] containsObject:key]) {
// contains key
}
hoặc là
if ([dictionary objectForKey:key]) {
// contains object
}
Các phiên bản gần đây hơn của Objective-C và Clang có cú pháp hiện đại cho việc này:
if (myDictionary[myKey]) {
}
Bạn không phải kiểm tra sự bằng nhau với nil, bởi vì chỉ các đối tượng Objective-C không phải nil mới có thể được lưu trữ trong từ điển (hoặc mảng). Và tất cả các đối tượng Objective-C là giá trị trung thực. Thậm chí @NO
,@0
và [NSNull null]
đánh giá là đúng.
Chỉnh sửa: Swift bây giờ là một điều.
Đối với Swift, bạn sẽ thử một cái gì đó như sau
if let value = myDictionary[myKey] {
}
Cú pháp này sẽ chỉ thực thi khối if nếu myKey nằm trong dict và nếu có thì giá trị được lưu trong biến giá trị. Lưu ý rằng điều này hoạt động cho các giá trị thậm chí falsey như 0.
Khi sử dụng từ điển JSON:
#define isNull(value) value == nil || [value isKindOfClass:[NSNull class]]
if( isNull( dict[@"my_key"] ) )
{
// do stuff
}
Tôi thích câu trả lời của Fernandes mặc dù bạn yêu cầu obj hai lần.
Điều này cũng nên làm (ít nhiều giống như A của 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
}
Cả Martin và câu trả lời này đều hoạt động trên iPad2 iOS 5.0.1 9A405
Một vấn đề rất khó chịu chỉ làm mất một chút thời gian của tôi để gỡ lỗi - bạn có thể thấy mình được nhắc nhở bằng cách tự động hoàn thành để thử sử dụng doesContain
dường như hoạt động.
Ngoại trừ, doesContain
sử dụng so sánh id thay vì so sánh băm được sử dụng bởi objectForKey
vì vậy nếu bạn có một từ điển với các khóa chuỗi, nó sẽ trả về NO cho 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
Đúng. Loại lỗi này rất phổ biến và dẫn đến sự cố ứng dụng. Vì vậy, tôi sử dụng để thêm NSDipedia trong mỗi dự án như sau:
Mã tập tin //.h:
@interface NSDictionary (AppDictionary)
- (id)objectForKeyNotNull : (id)key;
@end
Mã tệp //.m như dưới đây
#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
Trong mã bạn có thể sử dụng như dưới đây:
NSStrting *testString = [dict objectForKeyNotNull:@"blah"];
Để kiểm tra sự tồn tại của khóa trong NSDipedia:
if([dictionary objectForKey:@"Replace your key here"] != nil)
NSLog(@"Key Exists");
else
NSLog(@"Key not Exists");
Bởi vì nil không thể được lưu trữ trong cấu trúc dữ liệu Foundation NSNull
đôi khi để thể hiện a nil
. Bởi vì NSNull
là một đối tượng đơn lẻ, bạn có thể kiểm tra xem liệu NSNull
giá trị được lưu trong từ điển bằng cách sử dụng so sánh con trỏ trực tiếp:
if ((NSNull *)[user objectForKey:@"myKey"] == [NSNull null]) { }
NSNull
đã được lưu trong từ điển làm giá trị cho khóa @"myKey"
. Đó là một điều hoàn toàn khác với chìa khóa @"myKey"
không có trong từ điển - thực sự cả hai loại trừ lẫn nhau.
Giải pháp cho swift 4.2
Vì vậy, nếu bạn chỉ muốn trả lời câu hỏi liệu từ điển có chứa khóa hay không, hãy hỏi:
let keyExists = dict[key] != nil
Nếu bạn muốn giá trị và bạn biết từ điển chứa khóa, hãy nói:
let val = dict[key]!
Nhưng nếu, như thường xảy ra, bạn không biết nó chứa khóa - bạn muốn lấy nó và sử dụng nó, nhưng chỉ khi nó tồn tại - thì hãy sử dụng cái gì đó như if let
:
if let val = dict[key] {
// now val is not nil and the Optional has been unwrapped, so use it
}
Như Adirael đề nghị objectForKey
kiểm tra sự tồn tại của khóa nhưng khi bạn gọi objectForKey
trong từ điển nullable, ứng dụng bị lỗi nên tôi đã sửa lỗi này theo cách sau.
- (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"
}