使用冒号将NSString解析为NSDictionary

时间:2018-03-07 19:01:45

标签: ios objective-c

我正在尝试解析我遵循以下格式的字符串

Key: Object\n
Key: Object\n
Key: Object\n

进入NSDictionary,以便我更容易访问它。我的问题是:有没有更好的方法来实现这已经纳入obj-c?我的第一个想法是基于:和换行符的分离形成一个数组,然后使用偶数值作为键,奇数值作为对象,但这看起来有点过于复杂。

4 个答案:

答案 0 :(得分:3)

NSString *str = @"Key1: Object1\nKey2: Object2\nKey3: Object3\n";
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
NSArray *lines = [str componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
for (NSString *aKeyValue in lines)
{
    NSArray *components = [aKeyValue componentsSeparatedByString:@":"];
    if ([components count] != 2) continue; //Bypass stranges lines, like the last one
    NSString *key = [components[0] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    NSString *value = [components[1] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    [dict setObject:value forKey:key];
}

NSLog(@"Dict:\n%@", dict);

这给出了:

$> Dict:
{
    Key1 = Object1;
    Key2 = Object2;
    Key3 = Object3;
}

注意:我必须使用不同的键重命名您的String,因为它们必须是唯一的(否则,它将替换仅保留最后一个的值)。如果不是这样,您可能不想要NSDictionary

答案 1 :(得分:1)

此代码应该有效(在Swift中):

func parseString(_ str: String) -> Dictionary<String, String> {
    let lines = str.components(separatedBy: .newlines)
    var dict = [String: String]()
    for line in lines {
        let list = line.components(separatedBy: ": ")
        if list.count == 2 {
            dict[list[0]] = list[1]
        }
    }
    return dict
}

首先,我们创建一个带有线条的数组,然后对于每一行,我们提取由冒号分隔的键和值。

答案 2 :(得分:1)

撰写本文时提供的所有解决方案都会创建一系列行,然后处理这些行。 NSString提供方法enumerateLinesUsingBlock:以避免创建此中间行数组。假设您的字符串由变量str引用,则:

NSMutableDictionary *results = [NSMutableDictionary new];
[str enumerateLinesUsingBlock:^(NSString *line, BOOL *stop)
{
   NSArray<NSString *> *kvPair = [line componentsSeparatedByString:@":"]; // split key & value
   if (kvPair.count != 2) return; // ignore any line not matching "key : value"
   NSString *key = [kvPair[0] stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceCharacterSet]; // remove any whitespace
   NSString *value = [kvPair[1] stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceCharacterSet];
   results[key] = value;
}];

将在results生成字典。

注意:传递给块的stop参数是允许提前终止行枚举,在此示例中不使用它。但是,如果发现格式错误的行,则可以使用它来提前终止解析。

答案 3 :(得分:0)

使用Objective C没有更好的方法。这是你如何处理这个问题。用新行字符分隔字符串,然后再用&#34;:&#34;打破每个行字符串,将左边部分放在键上,右边部分放到值。

NSString *string = @"name: Jack Johnson\n\
                     address: Australia\n\
                     interest: Singing\n\";

NSString *trimmedString = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSArray *keyValuePairs = [trimmedString componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];

NSMutableDictionary *dict  = [NSMutableDictionary dictionary];

for (NSString *keyValuePair in keyValuePairs) {
    NSArray *keyValues = [keyValuePair componentsSeparatedByString:@":"];

    dict[[keyValues.firstObject stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]] = [keyValues.lastObject stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
}

NSLog(@"%@", dict);

像这样的东西。但这很快就像swift一样,

let keyValueTuple = string.trimmingCharacters(in: .whitespacesAndNewlines)
                            .components(separatedBy: .newlines)
                            .map { line -> (String, String) in
                                let keyValuePairs = line.components(separatedBy: CharacterSet(charactersIn: ":"))
                                let key = keyValuePairs.first!.trimmingCharacters(in: .whitespaces)
                                let value = keyValuePairs.last!.trimmingCharacters(in: .whitespaces)
                                return (key, value)
                                }
let dict = Dictionary(uniqueKeysWithValues: keyValueTuple)