【问题标题】:Is there a way to iterate over a dictionary?有没有办法遍历字典?
【发布时间】:2010-11-20 01:03:16
【问题描述】:

我知道NSDictionaries 需要key 才能获得value。但是我如何在NSDictionary 中遍历所有keysvalues,以便我知道有什么键,有什么值?我知道JavaScript 中有一个叫做 for-in-loop 的东西。 Objective-C有类似的吗?

【问题讨论】:

标签: ios objective-c foreach iteration nsdictionary


【解决方案1】:

这是使用块方法的迭代:

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

使用自动完成设置非常快,您不必担心编写迭代信封。

【讨论】:

  • 谢谢.. 如果您需要在过程中改变NSMutableDictionary,这是一个很好的解决方案
【解决方案2】:

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

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

即使NSDictionary 被实现为hashtable(这意味着查找元素的成本是O(1)),查找仍然会使您的迭代速度变慢一个常数因素

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

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

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

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

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

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

...大约快 40%

编辑:新的 SDK (6.1+) 似乎优化了循环迭代,因此循环方法现在比块方法快 20% 左右,至少对于上面的简单案例。

【讨论】:

  • 在 iOS 10/11 中,哪个更快?
  • 优雅,喜欢!
【解决方案3】:

是的,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]);

另一种方法(如果您的目标是 Mac OS X 10.5 之前的版本,但您仍然可以在 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]);

【讨论】:

  • ObjC 现代语法:NSLog(@"key=%@ value=%@", key, myDict[key]);
  • @Darthenius 由于最近的优化,快速枚举再次比基于块的更快,至少在某些情况下是这样。但是如果你正在解决的问题允许你使用并发选项,那么基于块的方法可能会更快。
  • @ZevEisenberg 看到我帖子的结尾。
  • 哎呀,我点击了上面的链接,在新标签页中打开,甚至没有注意到是谁写的或者它在同一页面上。如果您仍然可以编辑上面的评论,您可能会想要,以免懒惰的读者误会。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-03
  • 1970-01-01
  • 2016-01-16
  • 2016-05-03
  • 1970-01-01
  • 1970-01-01
  • 2016-09-21
相关资源
最近更新 更多