达到NSDictionary中最深的子级别

时间:2011-05-14 17:02:46

标签: iphone objective-c cocoa-touch ios nsdictionary

我有一个NSDictionary对象,其中包含深层结构,就像包含更多数组的数组一样,其中包含字典......

我想在层次结构中获取一个对象。是否有任何直接的索引方式来使用键名或其他东西来获取它们?

继续多次调用objectForKey方法以达到最深的孩子级别是一种痛苦。

3 个答案:

答案 0 :(得分:7)

如果您只使用字典,并且字典中的键始终是字符串,则可以使用key-value coding遍历多个级别的字典:

id someObject = [mainDictionary valueForKey:@"apple.pear.orange.bear"];

这相当于:

NSDictionary *level2Dict = [mainDictionary objectForKey:@"apple"];
NSDictionary *level3Dict = [level2Dict objectForKey:@"pear"];
NSDictionary *level4Dict = [level3Dict objectForKey:@"orange"];
id someObject = [level4Dict objectForKey:@"bear"];

但是,如果您在混音中也有数组,那么这不太方便。有关此主题的更多信息,请参阅this recent SO discussion

答案 1 :(得分:4)

对于包含Arrays的结构,没有内置方法可以执行以下操作:

[dict objectForKey:@"[level1][level2][level3]"]

话虽如此,内置的任何东西都只是Apple的某个人编写的代码,你可以这样做。

编写一个帮助程序类,它将根据您创建的密钥并置方案为您执行,然后只需调用它。它将保存代码重复。

答案 2 :(得分:3)

//
//  NSDictionary+Path.h
//
//  Created by Wu Li-chih on 10/3/12.
//  Copyright (c) 2012 Wu Li-chih. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface NSDictionary (Path)
- (id) objectForPath:(NSArray*)aKeyPath;
@end

//
//  NSDictionary+Path.m
//
//  Created by Wu Li-chih on 10/3/12.
//  Copyright (c) 2012 Wu Li-chih. All rights reserved.
//

#import "NSDictionary+Path.h"

@implementation NSDictionary (Path)

- (id) objectForPath:(NSArray*)aKeyPath
{
    if([d isKindOfClass:[NSDictionary class]])
        d = [d objectForKey:aKey];
    else if([d isKindOfClass:[NSArray class]])
        d = [d objectAtIndex:[aKey integerValue]];
    else
        return nil;
    if(d == nil)
        return nil;
}


@end

// example
id v = [dict objectForPath:@[@"root", @"sub", @"target_node"]];

NSDictionary *a = @{ @"aaa" : @{ @"bbb": @[@123, @456, @{@"ccc": @"result"}]}};
id r = [a objectForPath:@[@"aaa", @"bbb", @2, @"ccc"]];
STAssertTrue([r isEqualToString:@"result"], nil);
r = [a objectForPath:@[@"aaa", @"bbb", @0, @"ccc"]];
STAssertNil(r, nil);