目标:使用优雅代码获取包含给定NSDictionary的唯一键的NSArray
使用当前工作解决方案的示例代码:
NSArray *data = [[NSArray alloc] initWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:1], @"a", [NSNumber numberWithInt:2], @"b", nil],
[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:3], @"b", [NSNumber numberWithInt:4], @"c", nil],
[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:5], @"a", [NSNumber numberWithInt:6], @"c", nil],
[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:7], @"b", [NSNumber numberWithInt:8], @"a", nil],
[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:8], @"c", [NSNumber numberWithInt:9], @"b", nil],
nil];
// create an NSArray of all the dictionary keys within the NSArray *data
NSMutableSet *setKeys = [[NSMutableSet alloc] init];
for (int i=0; i<[data count]; i++) {
[setKeys addObjectsFromArray:[[data objectAtIndex:i] allKeys]];
}
NSArray *arrayKeys = [setKeys allObjects];
NSLog(@"arrayKeys: %@", arrayKeys);
返回所需的键数组:
2012-06-11 16:52:57.351 test.kvc[6497:403] arrayKeys: (
a,
b,
c
)
问题:有更优雅的方式来接近这个吗?当然必须有一些KVC方法可以获得所有的密钥,而不必遍历数组?我一直在看Apple Developer Documentation,看不到解决方案。有任何想法吗? (看纯粹优雅的代码而不是表现)。
答案 0 :(得分:8)
通常你可以通过这样的方式使用KVC:
NSArray *uniqueKeys = [data valueForKeyPath:@"@distinctUnionOfArrays.allKeys";
但是NSDictionary
会覆盖KVC内部使用的valueForKey:
选择器,因此无法正常工作。
documentation for NSDictionary's valueForKey:
method告诉我们:
如果key不以“@”开头,则调用objectForKey:。如果key以“@”开头,则删除“@”并使用其余键调用[super valueForKey:]。
所以我们只需在allKeys:
之前插入一个@
NSArray *uniqueKeys = [data valueForKeyPath:@"@distinctUnionOfArrays.@allKeys"];
我们得到了我们想要的东西:
(lldb) po [data valueForKeyPath:@"@distinctUnionOfArrays.@allKeys"]
(id) $14 = 0x07bb2fc0 <__NSArrayI 0x7bb2fc0>(
c,
a,
b
)
答案 1 :(得分:0)
我认为这不那么难看,而且可能稍快一些:
NSMutableSet *setKeys = [[NSMutableSet alloc] init];
for (NSDictionary* dict in data) {
for (id key in [dict keyEnumerator]) {
[setKeys addObject:key];
}
}
但是你没有做一个特别常见的操作,所以我不希望找到一些非常优雅的方法。如果这就是你想要的,那就去学习Haskell。
答案 2 :(得分:0)
你可以试试这个:
NSMutableSet *setKeys = [[NSMutableSet alloc] init];
for(NSDictionary *dict in data) {
[setKeys addObjectsFromArray:[dict allKeys]];
}
NSArray *arrayKeys = [setKeys allObjects];
如果你喜欢积木,你可以使用它:
[data enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[setKeys addObjectsFromArray:[obj allKeys]];
}];