在我的应用程序中,我需要将值插入到仅具有最后路径组件的NSDictionary中。例如。我的命令是
a = 1;
b = 2;
c = 3;
d = {
e = 4;
f = 5;
g = {
h = 6;
};
};
j = {
k = 7;
};
我需要更改k
的值。路径组件应为@[@"j", @"k"]
。我尝试了类似的东西:
- (void)recurse:(NSDictionary*)dict keyToFound:(NSString*)ktf stack:(NSMutableArray*)stack parent:(NSString*)parent
{
for (NSString *key in [dict allKeys]) {
if ([key isEqualToString:ktf]) {
[stack insertObject:key atIndex:[stack count]];
return;
}
else {
if ([[dict valueForKey:key] isKindOfClass:[NSDictionary class]]) {
NSDictionary *d = [dict valueForKey:key];
[stack insertObject:key atIndex:[stack count]];
[self recurse:d keyToFound:ktf stack:stack parent:key];
//[stack removeObject:key];
}
}
}
}
但是,obviuos,这是一种错误的方式。
答案 0 :(得分:1)
以下是在嵌套字典中设置值的两种更简单的方法。第一个假设您知道密钥存在并且可能是C标识符。在这种情况下,使用setValue:forKeyPath:
是最好的方法。否则,函数中的简单循环(或NSDictionary上的方法或类别)将起到作用:
void setValueForPathComponentsOfDictionary(id value, NSArray *components, NSMutableDictionary *dict) {
NSMutableArray *parts = [components mutableCopy];
id lastPart = parts.lastObject;
[parts removeLastObject];
for (id part in parts) {
if (![dict respondsToSelector:@selector(objectForKey:)])
return; // Silently fail.
dict = [dict objectForKey:part];
}
if ([dict respondsToSelector:@selector(objectForKey:)])
[dict setValue:value forKey:lastPart];
}
int main (int argc, const char * argv[])
{
@autoreleasepool {
NSMutableDictionary *dict = [@{
@"a":[@{@"a":@1,@"b":@2} mutableCopy],
@"b":[@{@"a":@3,@"b":@4} mutableCopy]
} mutableCopy];
NSLog(@"Initial Dictionary: %@", dict);
[dict setValue:@9 forKeyPath:@"a.b"];
NSLog(@"After setValue:forKeyPath: %@", dict);
setValueForPathComponentsOfDictionary(@0, @[@"b",@"a"], dict);
NSLog(@"After setValueForPathComponentsOfDictionary %@", dict);
}
return 0;
}
答案 1 :(得分:0)
好的,我找到了解决方案。
- (BOOL)recurse:(NSDictionary*)dict keyToFound:(NSString*)ktf stack:(NSMutableArray*)stack parent:(NSString*)parent
{
BOOL result = NO;
for (NSString *key in [dict allKeys]) {
if ([key isEqualToString:ktf]) {
[stack insertObject:key atIndex:[stack count]];
return YES;
}
else {
if ([[dict valueForKey:key] isKindOfClass:[NSDictionary class]]) {
NSDictionary *d = [dict valueForKey:key];
[stack insertObject:key atIndex:[stack count]];
result = [self recurse:d keyToFound:ktf stack:stack parent:key];
if (!result) {
[stack removeLastObject];
}
}
}
}
return result;
}
答案 2 :(得分:0)
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:@1,@"a",
@1,@"b",
@2,@"c",
[NSMutableDictionary dictionaryWithObjectsAndKeys:@4, @"e",
@5, @"f",
[NSMutableDictionary dictionaryWithObject:@6 forKey:@"h"], @"g", nil],@"d",
[NSMutableDictionary dictionaryWithObject:@7 forKey:@"k"],@"i",nil];
NSLog(@"Before %@",dict);
NSString *keyToChange = @"e";
NSString *valueToChange = @"Your New Value";
[dict enumerateKeysAndObjectsUsingBlock:^(id key ,id obj, BOOL *stop){
if([key isEqualToString:keyToChange])
{
NSLog(@"Found : %@",keyToChange);
if(![obj isKindOfClass:[NSArray class]] || ![obj isKindOfClass:[NSDictionary class]] || ![obj isKindOfClass:[NSMutableDictionary class]])
{
[dict setValue:@"newval" forKey:keyToChange];
return;
}
}
if([obj isKindOfClass:[NSDictionary class]])
{
[obj enumerateKeysAndObjectsUsingBlock:^(id key ,id obj1, BOOL *stop){
if([key isEqualToString:keyToChange])
{
if(![obj isKindOfClass:[NSArray class]] || ![obj isKindOfClass:[NSDictionary class]] || ![obj isKindOfClass:[NSMutableDictionary class]])
{
NSLog(@"Found : %@",keyToChange);
[obj setValue:@"newval" forKey:keyToChange];
return;
}
}
}];
}
}];
NSLog(@"After %@",dict);