cho mỗi vòng lặp trong Objective-C để truy cập từ điển NSMutable


268

Tôi đang gặp một số khó khăn trong việc truy cập các khóa và giá trị từ điển có thể thay đổi trong Objective-C.

Giả sử tôi có cái này:

NSMutableDictionary *xyz=[[NSMutableDictionary alloc] init];

Tôi có thể đặt khóa và giá trị. Bây giờ, tôi chỉ muốn truy cập từng khóa và giá trị, nhưng tôi không biết số lượng khóa được đặt.

Trong PHP nó rất dễ dàng, một cái gì đó như sau:

foreach ($xyz as $key => $value)

Làm thế nào có thể trong Objective-C?

Câu trả lời:


662
for (NSString* key in xyz) {
    id value = xyz[key];
    // do stuff
}

Điều này hoạt động cho mọi lớp tuân thủ giao thức NSFastEnumutions (có sẵn trên 10.5+ và iOS), mặc dù NSDictionarylà một trong số ít các bộ sưu tập cho phép bạn liệt kê các khóa thay vì các giá trị. Tôi đề nghị bạn đọc về liệt kê nhanh trong Chủ đề lập trình bộ sưu tập .

Ồ, tôi nên thêm vào tuy nhiên bạn KHÔNG BAO GIỜ sửa đổi một bộ sưu tập trong khi liệt kê nó.


4
Tôi đã tự hỏi, liệu nó có phải là: for (NSString * key trong [xyz allKeys]) ?? Hoặc nó không thực sự quan trọng.
FlowUI. SimpleUITesting.com

6
@ user76859403 Liệt kê một từ điển, trên thực tế, liệt kê các khóa. for (NSString* key in [xyz allKeys])về mặt khái niệm là điều tương tự.
zneak

Sử dụng [xyz allKeys] nếu bạn cần thay đổi từ điển trong khi liệt kê các khóa. Xem câu trả lời của tôi dưới đây.
Brody Robertson

Là vòng lặp này trở lại cùng một thứ tự tất cả các thời gian? Hay chúng ta cần một cách khác để sử dụng nó cho các phần TableView?
ymutlu

1
@ymutlu, từ điển ca cao không có thứ tự. Điều này có nghĩa là thứ tự lặp đi lặp lại có thể thay đổi bất cứ khi nào bạn sửa đổi chúng.
zneak

98

Chỉ cần không bỏ qua tùy chọn 10.6+ để liệt kê các khóa và giá trị bằng cách sử dụng các khối ...

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

Nếu bạn muốn các hành động xảy ra đồng thời:

[dict enumerateKeysAndObjectsWithOptions:NSEnumerationConcurrent
                              usingBlock:^(id key, id object, BOOL *stop) {
    NSLog(@"%@ = %@", key, object);
}];

2
3 cách khác nhau để liệt kê thông qua một từ điển. . . heh, điều này làm tôi nhớ đến câu trả lời "Tính năng ngôn ngữ lạ nhất" trong đó VB có 7 loại vòng lặp khác nhau.
dreamlax

3
Chà ... objectEnumerator đã được thêm vào năm 1994, for (... in ...) vào khoảng năm 2006, và Blocks đã được thêm vào năm 2009. Dạng khối của phép liệt kê là bụi phóng xạ tự nhiên.
bbum

Điều này dường như nhanh hơn tiêu chuẩn cho ... trong cấu trúc: oneofthesedaysblog.com/block-vs-for-in-objective-c-enumutions
lkraider

1
@lkraider, tôi đã nhận xét về bài đăng đó, trong đó thực sự so sánh phép liệt kê dựa trên khối với một vòng lặp for cũ, không phải cho ... trong cấu trúc.
Quinn Taylor

Để làm gì *stop? Làm thế nào để bạn sử dụng nó? Bất kỳ tài liệu tham khảo?
Boronomiakur

13

Nếu bạn cần thay đổi từ điển trong khi liệt kê:

for (NSString* key in xyz.allKeys) {
    [xyz setValue:[NSNumber numberWithBool:YES] forKey:key];
}

Lý do là allKeystrả về một bản sao của các phím. Vì vậy, nó an toàn để đột biến từ điển.
Honghao Zhang

5

Cách dễ nhất để liệt kê một từ điển là

for (NSString *key in tDictionary.keyEnumerator) 
{
    //do something here;
}

nơi tDictionaryNSDictionaryhoặc NSMutableDictionarybạn muốn lặp.



2

Phép liệt kê nhanh đã được thêm vào trong 10.5 và trong HĐH iPhone, và nó nhanh hơn đáng kể, không chỉ là đường cú pháp. Nếu bạn phải nhắm mục tiêu thời gian chạy cũ hơn (tức là 10,4 trở về trước), bạn sẽ phải sử dụng phương pháp liệt kê cũ:

NSDictionary *myDict = ... some keys and values ...
NSEnumerator *keyEnum = [myDict keyEnumerator];
id key;

while ((key = [keyEnum nextObject]))
{
    id value = [myDict objectForKey:key];
    ... do work with "value" ...
}

Bạn không giải phóng đối tượng liệt kê và bạn không thể đặt lại nó. Nếu bạn muốn bắt đầu lại, bạn phải yêu cầu một đối tượng liệt kê mới từ từ điển.


1

Bạn có thể sử dụng -[NSDictionary allKeys]để truy cập tất cả các khóa và lặp qua nó.


2
Đúng, nhưng điều này không tạo ra một mảng tự động thêm, có thể khá lãng phí, đặc biệt là đối với các từ điển có nhiều khóa.
Quinn Taylor
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.