有没有办法迭代字典?

195 iteration foreach objective-c nsdictionary ios

我知道NSDictionaries你需要一个东西,key以获得一个value.但是我如何迭代所有keysvaluesa NSDictionary,以便我知道有哪些键,以及有什么值?我知道有一种称为for-in-loop的东西JavaScript.有类似的东西Objective-C吗?

Ada*_*eld 313

是的,NSDictionary支持快速枚举.使用Objective-C 2.0,您可以这样做:

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

替代方法(如果你的目标是10.5之前的Mac OS X,但你仍然可以在10.5和iPhone上使用,则必须使用)是使用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]);
Run Code Online (Sandbox Code Playgroud)

  • 块方法更快.请参见http://stackoverflow.com/a/12454766/974531. (4认同)
  • ObjC现代语法:NSLog(@"key =%@ value =%@",key,myDict [key]); (2认同)

Rok*_*iša 150

块方法避免了为每个键运行查找算法:

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

尽管NSDictionary实现为哈希表(这意味着O(1)查找元素的成本是),但查找仍然会使迭代速度减慢一个常数因子.

我的测量表明,对于d数字字典......

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

......用块方法总结数字......

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

...而不是循环方法......

int sum = 0;
for (NSString* key in dict)
  sum += [dict[key] intValue];
Run Code Online (Sandbox Code Playgroud)

...... 快了大约40%.

编辑:新的SDK(6.1+)似乎优化循环迭代,因此循环方法现在比块方法快约20%,至少对于上面的简单情况.


Jav*_*ría 9

这是使用块方法的迭代:

    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.
    }];
Run Code Online (Sandbox Code Playgroud)

自动完成设置非常快,您不必担心编写迭代包络.