2

In C++ one can declare iterator on map. Then iterator can be promoted and saved, thus iteration can be resumed later from the saved position.

How to do the same in Obj-C efficiently?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
BorisV
  • 683
  • 3
  • 20
  • You've already noted that the dictionary can be mutated, but did you know that you're [not guaranteed the same order of keys when you enumerate a dictionary repeatedly](https://stackoverflow.com/questions/1295459/are-keys-and-values-in-an-nsdictionary-ordered)? What are you really trying to do? Can you make an immutable copy of the dictionary and retain that (and it's enumerator) somewhere? – Michael Dautermann Aug 16 '17 at 19:21
  • You can try to put the keys into an array, and iterate through it. Arrays are ordered comparing to maps (or actually Dictionaries in Obj-C / Swift languages), so you're good to save and restore your position. – choofie Aug 16 '17 at 19:23
  • I really try to save the iterator and proceed later from the saved point. My goal is to iterate on dictionary and have same order of enumeration if the dictionary was not altered. Efficiently. – BorisV Aug 16 '17 at 19:25
  • @choofie, I think performing search in dictionary each time is a little expensive. – BorisV Aug 16 '17 at 19:29
  • @Boris You don't need to perform search. The main difference between C++ map and Objective-C NSDictionary is that it's unordered. You just need an ordered sequence to keep the keys of your dictionary ordered. Then if you want to iterate through your `NSMutableDictionray`, basically you're going to iterate the keys `NSArray` instead, and use the actual iteration's key to lookup your dictionary. – choofie Aug 16 '17 at 19:40
  • I mean lookup with the key every time - isn't it expensive? – BorisV Aug 16 '17 at 19:47
  • @Boris I don't think so. You can try give a go with my code in the answers. – choofie Aug 16 '17 at 19:56
  • There's [`-objectEnumerator`](https://developer.apple.com/documentation/foundation/nsdictionary/1409600-objectenumerator?language=objc), but I doubt it's safe to save for a mutable dictionary. – jscs Aug 16 '17 at 20:13
  • Compare [Is there a way to iterate over a dictionary?](https://stackoverflow.com/questions/1284429/is-there-a-way-to-iterate-over-a-dictionary) – Martin R Aug 16 '17 at 20:17

1 Answers1

2

Try to create an ordered array with the keys of your dictionary and iterate it. You can break out from the for loop anytime. The currentIteration var makes sure to store the last iteration, that you can use next time for resuming.

NSMutableDictionary *dictionary = @{@"key1" : @"value1", @"key2" : @"value2", @"key3" : @"value3"};
NSArray *keys = dictionary.allKeys;
int currentIteration = 0;

for (int i = 0; i < keys.count; i++) {
    currentIteration = i;
    NSObject *value = dictionary[keys[i]];
    NSLog(@"%@", value);
}
choofie
  • 2,575
  • 1
  • 25
  • 30
  • I get it. I say that lookup every time seems to be expensive. Is there any way to avoid it? – BorisV Aug 16 '17 at 19:56
  • 1
    @Boris it's like a hash. See here https://developer.apple.com/library/content/documentation/CoreFoundation/Conceptual/CFCollections/Articles/types.html#//apple_ref/doc/uid/20001129-102779-CHDBEIHH – danh Aug 16 '17 at 21:16