0

目的:エレガントなコードを使用して、特定の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を見てきましたが、解決策が見つかりません。何か案は?(パフォーマンスではなく、純粋にコードの優雅さを見てください)。

4

3 に答える 3

8

通常、次のようにしてKVCを使用できます。

NSArray *uniqueKeys = [data valueForKeyPath:@"@distinctUnionOfArrays.allKeys";

ただし、KVC内部で使用されるセレクターをNSDictionaryオーバーライドするvalueForKey:ため、これは正しく機能しません。

NSDictionaryのvalueForKey:メソッドのドキュメントには、次のことが記載されています。

キーが「@」で始まらない場合は、objectForKey:を呼び出します。キーが「@」で始まる場合は、「@」を削除し、残りのキーで[super valueForKey:]を呼び出します。

したがって、@allKeysの前に挿入するだけです。

NSArray *uniqueKeys = [data valueForKeyPath:@"@distinctUnionOfArrays.@allKeys"];

そして、私たちは欲しいものを手に入れます:

(lldb) po [data valueForKeyPath:@"@distinctUnionOfArrays.@allKeys"]
(id) $14 = 0x07bb2fc0 <__NSArrayI 0x7bb2fc0>(
c,
a,
b
)
于 2012-06-11T07:36:22.363 に答える
0

これは醜くなく、おそらくわずかに速いと思います。

NSMutableSet *setKeys = [[NSMutableSet alloc] init]; 
for (NSDictionary* dict in data) {
    for (id key in [dict keyEnumerator]) {
        [setKeys addObject:key];
    }
}

しかし、あなたは特に一般的な操作を行っていないので、信じられないほどエレガントな方法を見つけることは期待できません。それがあなたが望むものなら、Haskellを学びに行ってください。

于 2012-06-11T07:15:33.963 に答える
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]];
}];
于 2012-06-11T07:22:44.647 に答える