我有一个NSDictionary对象,其中包含深层结构,就像包含更多数组的数组一样,其中包含字典......
我想在层次结构中获取一个对象。是否有任何直接的索引方式来使用键名或其他东西来获取它们?
继续多次调用objectForKey方法以达到最深的孩子级别是一种痛苦。
答案 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);