2013-06-26 62 views
0

我有一个NSMutableDictionary * A(来自in.plist)。我需要用A自动修改的整数在A和A的后代字典中为每个键添加前缀,并将结果保存在NSMutableDictionary B(保存为out.plist)中。NSMutableDictinary - 为所有键添加前缀

达到此目的的最佳方法是什么?递归?循环? Fastenum?

PS:我们不知道提前字典A的结构,它可以包括字典阵列字典...等等

例子:

in.plist out.plist - Change only the key http://img11.hostingpics.net/pics/698162Capturedcran201306262025.png

唯一的差异输入和输出字典之间是密钥名称。

我发现在plist文件用Perl的正则表达式一个直接的解决方法:

cat in.plist | perl -ne 's/<key>/sprintf("<key>%02d -",($INDEX++))/xe;print $_' > out.plist 

就像一个魅力,但一个喜欢Objective-C的方式。

+0

订单重要吗? – Chuck

+0

不,我不关心订单 – Elfoiros

+0

用于前缀键名的整数必须是唯一的 – Elfoiros

回答

2

这有点奇怪,但这里基本上是你想要做的。创建一个新的NSMutableDictionary。对原始字典进行深度优先遍历,并且每次遇到密钥时,都要在将它设置在新字典中之前加上数字。下面是一个例子实现(写在浏览器中,所以警告执行人):

NSDictionary *numberDict(NSDictionary *original) { 
    __block int counter = 1; 

    __block id (^processItem)(id); 
    processItem = ^(id item) { 
     id result = item; 
     if ([item isKindOfClass:[NSArray class]]) { 
      result = [NSMutableArray array]; 
      [item enumerateObjectsUsingBlock:^(id arrayElement, NSUInteger index, BOOL *stop) { 
       [result addObject:processItem(arrayElement)]; 
      }]; 
     } else if ([item isKindOfClass:[NSDictionary class]]) { 
      result = [NSMutableDictionary dictionary]; 
      [item enumerateKeysAndObjectsUsingBlock:^(NSString *key, id value, BOOL *stop) { 
       NSString *newKey = [NSString stringWithFormat:@"%d - %@", counter++, key]; 
       [result setObject:processItem(value) forKey:newKey]; 
      }]; 
     } 
     return result; 
    }; 
    return processItem(original); 
} 

显然,这将不保留字典键的顺序,因为字典键实际上没有被保存的命令,但你已经表明你知道,并确定。

+0

语法应该是* id(^ processItem)(id)=^id(id item)*是正确的。但是* processItem *在它自己内部引用,它应该是* __ block * too(id(^ __ block processItem)(id)=^id(id item))。这会创建一个保留周期,我认为如果您对该方法进行递归而不是在块上进行递归会更好。 +1然而,对于漂亮的技术。 –

+0

@RamyAlZuhouri:这是一个本地块。不可能有保留周期。但正确的语法。我认为在方法上进行递归会要求我们使用某种全局状态,参数列表中的指针或其他额外的簿记来维护我们的计数器,这会比这更混乱。但我可能不会以正确的方式思考它。 – Chuck

+0

好吧,但* processItem *也应该是* __ block *,这就是他得到* EXC_BAD_ACCESS *的原因。我感谢编译器的警告。 –