Có cách nào để lặp lại từ điển không?


200

Tôi biết NSDictionariesnhư một cái gì đó mà bạn cần một keyđể có được một value. Nhưng làm thế nào tôi có thể lặp lại tất cả keysvaluestrong một NSDictionary, để tôi biết có những khóa nào, và những giá trị nào có? Tôi biết có một cái gì đó gọi là for-in-loop in JavaScript. Có một cái gì đó tương tự trong Objective-C?


Cảm ơn cho bài viết này. Nếu lặp theo Swiftcú pháp, hãy tham khảo bài đăng này: stackoverflow.com/a/24111700/419348
AechoLiu

Câu trả lời:


323

Có, NSDictionaryhỗ trợ liệt kê nhanh. Với Objective-C 2.0, bạn có thể làm điều này:

// To print out all key-value pairs in the NSDictionary myDict
for(id key in myDict)
    NSLog(@"key=%@ value=%@", key, [myDict objectForKey:key]);

Phương pháp thay thế (mà bạn phải sử dụng nếu bạn nhắm mục tiêu Mac OS X trước 10.5, nhưng bạn vẫn có thể sử dụng trên 10.5 và iPhone) là sử dụng NSEnumerator:

NSEnumerator *enumerator = [myDict keyEnumerator];
id key;
// extra parens to suppress warning about using = instead of ==
while((key = [enumerator nextObject]))
    NSLog(@"key=%@ value=%@", key, [myDict objectForKey:key]);

2
Cú pháp hiện đại của ObjC: NSLog (@ "key =% @ value =% @", key, myDict [key]);
geowar

@Darthenius do tối ưu hóa gần đây, liệt kê nhanh một lần nữa nhanh hơn dựa trên khối, ít nhất là trong một số trường hợp nhất định. Nhưng nếu vấn đề bạn đang giải quyết cho phép bạn sử dụng tùy chọn đồng thời, cách tiếp cận dựa trên khối có thể nhanh hơn.
Zev Eisenberg

@ZevEisenberg Xem phần cuối bài viết của tôi.
Rok Strniša

Rất tiếc, tôi đã nhấp vào liên kết của bạn, ở trên, để mở trong một tab mới và thậm chí không nhận thấy ai đã viết nó hoặc nó ở trên cùng trang này. Nếu bạn vẫn có thể chỉnh sửa nhận xét trên, bạn có thể muốn, để những người đọc lười biếng không hiểu sai.
Zev Eisenberg

153

Cách tiếp cận khối tránh chạy thuật toán tra cứu cho mọi khóa :

[dict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL* stop) {
  NSLog(@"%@ => %@", key, value);
}];

Mặc dù NSDictionaryđược triển khai dưới dạng hashtable (có nghĩa là chi phí tìm kiếm một phần tử là O(1)), việc tra cứu vẫn làm chậm quá trình lặp của bạn bởi một yếu tố không đổi .

Các phép đo của tôi cho thấy rằng đối với một từ điển dsố ...

NSMutableDictionary* dict = [NSMutableDictionary dictionary];
for (int i = 0; i < 5000000; ++i) {
  NSNumber* value = @(i);
  dict[value.stringValue] = value;
}

... tổng hợp các con số với cách tiếp cận khối ...

__block int sum = 0;
[dict enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSNumber* value, BOOL* stop) {
  sum += value.intValue;
}];

... thay vì cách tiếp cận vòng lặp ...

int sum = 0;
for (NSString* key in dict)
  sum += [dict[key] intValue];

... Nhanh hơn khoảng 40% .

EDIT : SDK mới (6.1+) xuất hiện để tối ưu hóa vòng lặp, do đó, cách tiếp cận vòng lặp hiện nhanh hơn khoảng 20% ​​so với cách tiếp cận khối , ít nhất là đối với trường hợp đơn giản ở trên.


Còn trong iOS 10/11, cái nào nhanh hơn?
Supertecnoboff

thanh lịch, yêu nó!
YvesLeBorg

10

Đây là phép lặp sử dụng phương pháp khối:

    NSDictionary *dict = @{@"key1":@1, @"key2":@2, @"key3":@3};

    [dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        NSLog(@"%@->%@",key,obj);
        // Set stop to YES when you wanted to break the iteration.
    }];

Với tính năng tự động hoàn thành rất nhanh để thiết lập và bạn không phải lo lắng về việc viết phong bì lặp.


Cảm ơn .. Giải pháp tốt nếu bạn cần thay đổi NSMutableDictionaryquy trình
jose920405
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.