Bir sözlük üzerinde yineleme yapmanın bir yolu var mı?


200

Bir NSDictionariesşey keyelde etmek için ihtiyacınız olan bir şey olarak biliyorum value. Ama nasıl baştan ben yinelerler edebilir keysve valuesbir de NSDictionaryben anahtarları orada ne olduğunu böylece ve ne var değerleri? Döngü içinde denilen bir şey olduğunu biliyorum JavaScript. Benzer bir şey var mı Objective-C?


Bu gönderi için teşekkürler. SwiftSözdiziminde yineleme
yapıyorsanız

Yanıtlar:


323

Evet, NSDictionaryhızlı numaralandırmayı destekler. Objective-C 2.0 ile şunları yapabilirsiniz:

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

Alternatif yöntem (Mac OS X 10.5 öncesi hedefliyorsanız, ancak yine de 10.5 ve iPhone'da kullanabiliyorsanız) kullanmanız gereken bir yöntem 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
ObjC modern sözdizimi: NSLog (@ "anahtar =% @ değer =% @", anahtar, myDict [anahtar]);
geowar

@Darthenius, son optimizasyonlar nedeniyle, hızlı numaralandırma, en azından bazı durumlarda, blok tabanlı olandan daha hızlıdır. Ancak çözmekte olduğunuz sorun eşzamanlı seçeneği kullanmanıza izin veriyorsa, blok tabanlı yaklaşım daha hızlı olabilir.
Zev Eisenberg

@ZevEisenberg Yazımın sonuna bakın.
Rok Strniša

Hata! Yeni bir sekmede açmak için yukarıdaki bağlantınızı tıkladım ve kimin yazdığını veya aynı sayfada olduğunu fark etmedim. Yukarıdaki yorumu yine de düzenleyebiliyorsanız, tembel okuyucuların yanlış fikri almaması için isteyebilirsiniz.
Zev Eisenberg

153

Blok yaklaşımı , her anahtar için arama algoritmasını çalıştırmayı önler :

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

Her ne NSDictionarykadar bir karma tablo olarak uygulansa da (bir öğeye bakmanın maliyeti olduğu anlamına gelir O(1)), aramalar yinelemenizi sabit bir faktörle yavaşlatır .

Ölçümlerim bir dsayı sözlüğü için ...

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

... sayıları blok yaklaşımı ile özetliyor ...

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

... döngü yaklaşımı yerine ...

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

... yaklaşık% 40 daha hızlı .

DÜZENLEME : Yeni SDK (6.1+) döngü yinelemeyi optimize ediyor gibi göründüğünden , döngü yaklaşımı artık en azından yukarıdaki basit durum için blok yaklaşımından yaklaşık% 20 daha hızlıdır .


İOS 10/11'de hangisi daha hızlı?
Supertecnoboff

zarif, seviyorum!
YvesLeBorg

10

Bu, blok yaklaşımı kullanan yineleme:

    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.
    }];

Otomatik tamamlama ayarı çok hızlıdır ve yineleme zarfı yazma konusunda endişelenmenize gerek yoktur.


Teşekkürler .. NSMutableDictionarysürecinde mutasyona ihtiyacınız varsa iyi bir çözüm
jose920405
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.