有没有办法迭代字典?

发布于 2024-08-02 20:17:51 字数 168 浏览 6 评论 0原文

我知道 NSDictionaries 是需要一个键才能获取值的东西。但是我如何迭代 NSDictionary 中的所有键和值,以便我知道有哪些键以及有哪些值?我知道 JavaScript 中有一种叫做 for-in-loop 的东西。 Objective-C 中有类似的东西吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

弥繁 2024-08-09 20:17:51

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

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]);
蓝海似她心 2024-08-09 20:17:51

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

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

即使NSDictionary 实现为 哈希表(这意味着查找元素的成本为 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%,至少对于简单的情况是这样多于。

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 is implemented as a hashtable (which means that the cost of looking up an element is O(1)), 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.

jJeQQOZ5 2024-08-09 20:17:51

这是使用块方法的迭代:

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

使用自动完成功能可以非常快地设置,并且您不必担心编写迭代信封。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文