Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 644 Vote(s) - 3.54 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Is there a way to iterate over a dictionary?

#1
I know `NSDictionaries` as something where you need a `key` in order to get a `value`. But how can I iterate over all `keys` and `values` in a `NSDictionary`, so that I know what keys there are, and what values there are? I know there is something called a *for-in-loop* in `JavaScript`. Is there something similar in `Objective-C`?
Reply

#2
Yes, `NSDictionary` supports fast enumeration. With Objective-C 2.0, you can do this:

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

The alternate method (which you have to use if you're targeting Mac OS X pre-10.5, but you can still use on 10.5 and iPhone) is to use an `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]);
Reply

#3
**The block approach** avoids running the lookup algorithm for *every key*:

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

Even though [`NSDictionary`][1] is implemented as a [hashtable][2] (which means that the cost of looking up an element is [`O(1)`][3]), lookups still slow down your iteration by *a constant factor*.

My measurements show that for a dictionary `d` of numbers ...

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

... summing up the numbers with the block approach ...

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

... rather than the loop approach ...

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

... **is about 40% faster**.

**EDIT**: The new SDK (6.1+) appears to optimise loop iteration, so **the loop approach is now about 20% faster than the block approach**, at least for the simple case above.

[1]:

[To see links please register here]

[2]:

[To see links please register here]

[3]:

[To see links please register here]

Reply

#4
This is iteration using block approach:

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

With autocompletion is very fast to set, and you do not have to worry about writing iteration envelope.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through