【问题标题】:NSMutableDictinary - Add prefix to all keysNSMutableDictinary - 为所有键添加前缀
【发布时间】:2013-06-26 18:33:43
【问题描述】:

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

实现这一目标的最佳方法是什么?递归?环形 ?紧固件?

PS:我们事先并不知道字典A的结构,它可以包括字典数组字典...等等

例子:

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

in 和 out 字典之间的唯一区别是键名。

我在 plist 文件中直接找到了使用 perl 正则表达式的解决方法:

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

像魅力一样工作,但更喜欢 Objective-c 方式。

【问题讨论】:

  • 订单重要吗?
  • 不,我不在乎订单
  • 用于前缀键名的整数必须是唯一的
  • 将其写为 JSON 并编辑 JSON。 (或者对 plist/XML 格式做同样的事情。)甚至可能使用 RE 来做这些脏活。

标签: objective-c plist nsdictionary nsmutabledictionary


【解决方案1】:

这有点奇怪,但这基本上是您想要做的。制作一个新的 NSMutableDictionary。对原始字典进行深度优先遍历,每次遇到键时,在将其设置到新字典之前添加您的数字。这是一个示例实现(用浏览器编写,所以 caveat executor):

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);
}

显然这不会保留字典键的顺序,因为字典键实际上没有要保留的顺序,但您已经表明您知道并且可以接受。

【讨论】:

  • 正确的语法应该是 id (^processItem)(id) = ^id(id item)。但是 processItem 在其内部被引用,它也应该是 __block (id (^__block processItem)(id) = ^id(id item) )。这会创建一个保留周期,我认为最好对方法而不是块进行递归。但是,+1 是因为技术不错。
  • @RamyAlZuhouri:这是一个本地街区。不能有保留周期。但是在语法上。而且我认为对方法进行递归将需要我们使用某种全局状态、参数列表中的指针或其他额外的簿记来维护我们的计数器,这会比这更混乱。但我不能以正确的方式思考它。
  • 好吧,但是 processItem 也应该是 __block,这就是他得到 EXC_BAD_ACCESS 的原因。由于编译器警告,我看到了它。
  • 顺便说一句,也使用 __block 计数器意味着具有全局状态,我使用指针参数做到了,代码在 IMO 中更加流畅和优雅。
  • @RamyAlZuhouri:不确定你的意思。 counter 变量对方法来说是严格的本地变量。您可以同时在五个不同字典上的五个线程中运行此函数并获得正确的结果,所以我不确定您在什么意义上使用“全局”。而且我猜“优雅”是个人品味的问题,但据我所知,计数器是算法的内部状态,因此将其暴露在函数的接口中——要求调用者为计数器传递一些内存——不会对我来说似乎很优雅。
猜你喜欢
  • 1970-01-01
  • 2013-02-04
  • 2014-07-26
  • 2011-09-02
  • 2018-08-09
  • 2013-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多