【问题标题】:Creating dynamic NSMutableDictionary query with multiple values创建具有多个值的动态 NSMutableDictionary 查询
【发布时间】:2012-06-09 16:42:42
【问题描述】:

我正在做一个项目,我希望能够处理一些模板类型的消息。该模板将包含以下内容:

"{{user1}} has just created an account"

然后我有一个数据映射,它会在 NSMutableDictionary 中为您提供数据所在的位置:

"activity.message.status"

然后我希望能够通过拆分该字符串来查询 NSMutableDictionary,使其变为:

[[[myDictionary objectForKey:@"activity"] objectForKey:@"message"] objectForKey:@"status"]

我可以做一些东西,只要它是 3 弦,但有些可能或多或少。

任何帮助将不胜感激。

【问题讨论】:

  • [myDictionary valueForKeyPath:@"activity.message.status"]; 也应该可以工作
  • 谢谢马蒂亚斯!!你的例子正是我正在寻找的。您能否将其发布为答案,以便我将其标记为已接受的答案?

标签: iphone ios templates dynamic nsmutabledictionary


【解决方案1】:

这实际上比将字符串拆分为键要容易得多。 Apples Key-Value-Coding 正是您想要的。

[myDictionary valueForKeyPath:@"activity.message.status"];

键路径是一串点分隔键,用于指定要遍历的对象属性序列。序列中第一个键的属性是相对于接收者的,后续的每个键都是相对于前一个属性的值进行评估的。

例如关键路径address.street会从接收对象中获取address属性的值,然后确定相对于address对象的street属性。

Key-Value Coding Programming Guide

【讨论】:

  • 这是一个很好的答案,这可能是提问者真正需要的。该请求明确针对嵌套字典。
  • Matthias Bauch - 谢谢!这正是我想要的。很抱歉花了这么长时间才将其标记为已接受的答案。
【解决方案2】:

你会做类似的事情,

NSArray *array = [@"activity.message.status" componentsSeperatedByString:@"."];

这将创建一个包含{activity,message,status) 的数组。

现在您有了可以用于查询字典的数组。

[[[myDictionary objectForKey:[array objectAtIndex:0]] objectForKey:[array objectAtIndex:1]] objectForKey:[array objectAtIndex:2]];

相当于:

[[[myDictionary objectForKey:@"activity"] objectForKey:@"message"] objectForKey:@"status"];

希望这会有所帮助!

【讨论】:

  • 好主意 skram,但我想要一些基本可用的东西,而无需我手动编写语句,因为数组可以更大或更小。
【解决方案3】:

从您的问题中我不清楚我们应该如何将user1 映射到activity.message.status。现在我假设您的意思是该模板可能包含一个类似 "{{activity.message.status}}" 的字符串,并且您希望能够解析它。

这是一个在 NSMutableString 上运行的迭代,可以循环直到找不到匹配项:

NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\{\\{.+?\\}\\}"
                              options:NSRegularExpressionCaseInsensitive
                              error:&error];
NSRange matchRange = [regex rangeOfFirstMatchInString:string
                      options:0 range:NSMakeRange(0, [string length])];
NSRange keyPathRange = NSMakeRange(matchRange.location + 2, matchRange.length - 4);
NSString *keyPath = [string substringWithRange:keyPathRange];
NSString *newSubstring = [myDictionary valueForKeyPath:keyPath];
[string replaceCharactersInRange:matchRange withString:newSubstring];

我没有测试过这段代码。

【讨论】:

  • 替换模板位置的好例子,但我正在寻找一些东西来从字典中获取数据,然后在字符串中替换它检索的值。 Matthias 在我的问题帖子中的评论对我有用。
【解决方案4】:

NSMutableDictionary 上的(递归...酷)类别方法怎么样:

- (void)setObject:(id)object forCompoundKey:(NSString *)compoundKey {

    NSArray *keys = [compoundKey componentsSeparatedByString:@"."];

    if ([keys count] == 1) {
        return [self setObject:object forKey:compoundKey];
    }

    // get the first component of the key
    NSString *key = [keys objectAtIndex:0];

    // build the remaining key with the remaining components
    NSRange nextKeyRange;
    nextKeyRange.location = 1;
    nextKeyRange.length = [keys count] - 1;
    NSArray nextKeys = [keys subarrayWithRange:nextRange];
    NSString *nextKey = [nextKeys componentsJoinedByString:@"."];

    NSMutableDictionary *nextDictionary = [NSMutableDictionary dictionary];
    [self addObject:nextDictionary forKey:key];

    // now the cool part... recursion
    [nextDictionary setObject:object forCompoundKey:nextKey];
}

我没有对此进行测试,但它通过了快速桌面检查。 objectForCompoundKey: 检索可以类推。

【讨论】:

    猜你喜欢
    • 2019-08-09
    • 2017-01-06
    • 1970-01-01
    • 1970-01-01
    • 2019-06-05
    • 1970-01-01
    • 1970-01-01
    • 2011-01-08
    • 2016-06-16
    相关资源
    最近更新 更多