95

How do I loop through all objects in a NSMutableDictionary regardless of the keys?

Andrey Zverev
  • 4,409
  • 1
  • 28
  • 34
Rupert
  • 953
  • 1
  • 6
  • 5

6 Answers6

210

A standard way would look like this

for(id key in myDict) {
    id value = [myDict objectForKey:key];
    [value doStuff];
}
Henrik P. Hessel
  • 36,243
  • 17
  • 80
  • 100
  • If only there were a way of doing something like: `for (id key, value in myDict)` that would be perfect. – Luis Artola Jul 12 '13 at 17:32
  • 4
    Better to iterate through keys though (i.e. `id key in myDict.allKeys`), rather than the dictionary. This allows you to mutate the dictionary, which might be what you want to do. – marcel salathe May 18 '14 at 21:59
30

you can use

[myDict enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL *stop) {
    // do something with key and obj
}];

if your target OS supports blocks.

Andrey Zverev
  • 4,409
  • 1
  • 28
  • 34
23

You can use [dict allValues] to get an NSArray of your values. Be aware that it doesn't guarantee any order between calls.

jv42
  • 8,521
  • 5
  • 40
  • 64
  • 3
    I would use this one over the (id key in dictionary), especially on a mutable dictionary, since the latter throws a nasty error if the dictionary is modified while being enumerated. – sigsegv Oct 12 '10 at 13:56
  • "it doesn't guarantee" - this is frequently needed (most languages have a version of dictionary that DOES guarantee order) - does it *in practice* preserve order? – Adam Dec 25 '12 at 17:33
  • @Adam On MacOS X, I had pretty mixed up order (not order of insertion, not alphabetic, nothing), but consistent between calls. – jv42 Feb 24 '13 at 10:24
  • Why use a NSDictionary if the mappings don't matter? – stephen Mar 26 '13 at 03:41
  • 2
    @stephen Usually it matters somewhere and doesn't elsewhere. You also get the unique key constraint that might be useful for some cases. – jv42 Mar 26 '13 at 07:56
5
  1. For simple loop, fast enumeration is a bit faster than block-based loop
  2. It's easier to do concurrent or reverse enumeration with block-based enumeration than with fast enumeration When looping with NSDictionary you can get key and value in one hit with a block-based enumerator, whereas with fast enumeration you have to use the key to retrieve the value in a separate message send

in fast enumeration

for(id key in myDictionary) {
   id value = [myDictionary objectForKey:key];
  // do something with key and obj
}

in Blocks :

[myDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {

   // do something with key and obj
  }];
user3540599
  • 721
  • 9
  • 6
3

You don't need to assign value to a variable. You can access it directly with myDict[key].

    for(id key in myDict) {
        NSLog(@"Key:%@ Value:%@", key, myDict[key]);
    }
Alexander
  • 31
  • 4
2

Another way is to use the Dicts Enumerator. Here is some sample code from Apple:

NSEnumerator *enumerator = [myDictionary objectEnumerator];
id value;

while ((value = [enumerator nextObject])) {
    /* code that acts on the dictionary’s values */
}
Hendrik
  • 940
  • 8
  • 14