【问题标题】:Reduce a string to a dictionary in Swift在 Swift 中将字符串简化为字典
【发布时间】:2015-09-30 23:44:20
【问题描述】:

在 Swift 中将像 AAA:111;BBB:222;333;444;CCC:555 这样的字符串简化为字典的简单方法是什么?我有以下代码:

var str = "AAA:111;BBB:222;333;444;CCC:555"
var astr = str.componentsSeparatedByString(";").map { (element) -> [String:String] in
    var elements = element.componentsSeparatedByString(":")
    if elements.count < 2 {
        elements.insert("N/A", atIndex: 0)
    }
    return [elements[0]:elements[1]]
}


上面的代码产生了一个 DictionariesArray
[["A": "111"], ["BBB": "222"], ["UKW": "333"], ["UKW": "444"], ["CCC": "555"]]

我希望它产生
["A": "111", "BBB": "222", "UKW": "333", "UKW": "444", "CCC": "555"]

但无论我尝试什么,因为我在 Array 上调用 map 函数,因此似乎无法转换 map 函数结果的性质。

注意:字符串格式的字典被描述为具有KEY:VALUE; 格式或VALUE; 格式,在这种情况下,映射函数将添加"N/A" 作为未命名值的键。

非常感谢您对此事的任何帮助。

【问题讨论】:

    标签: arrays swift dictionary swift2


    【解决方案1】:

    您的map 会生成一个字典数组。当你想把它们合二为一时,这对reduce来说是一个完美的工作:

    func + <K,V>(lhs: Dictionary<K,V>, rhs: Dictionary<K,V>) -> Dictionary<K,V> {
        var result = Dictionary<K,V>()
    
        for (key, value) in lhs {
            result[key] = value
        }
        for (key, value) in rhs {
            result[key] = value
        }
    
        return result
    }
    
    var str = "AAA:111;BBB:222;333;444;CCC:555"
    var astr = str
        .componentsSeparatedByString(";")
        .reduce([String: String]()) {
            aggregate, element in
            var elements = element.componentsSeparatedByString(":")
            if elements.count < 2 {
                elements.insert("N/A", atIndex: 0)
            }
            return aggregate + [elements[0]:elements[1]]
        }
    
    print(astr)
    

    Swift 没有默认运算符来“组合”两个Dictionaries,因此您必须定义一个。注意这里的+ 不是可交换的:dictA + dictB != dictB + dictA。如果两个字典中都存在一个键,则将使用第二个字典中的值。

    【讨论】:

    • 这很好,但是你用+ 操作让它变得非常复杂。这根本不需要。
    【解决方案2】:

    这是reduce的作品:

    let str = "AAA:111;BBB:222;333;444;CCC:555"
    let keyValueStrings = str.componentsSeparatedByString(";")
    let dictionary = keyValueStrings.reduce([String: String]()) {
        aggregate, element in
    
        var newAggregate = aggregate
    
        let elements = element.componentsSeparatedByString(":")
        let key = elements[0]
    
        // replace nil with the value you want to use if there is no value        
        let value = (elements.count > 1) ? elements[1] : nil
        newAggregate[key] = value
    
        return newAggregate
    }
    
    print(dictionary)
    

    你也可以直接使aggregate可变:

    let dictionary = keyValueStrings.reduce([String: String]()) {
        (var aggregate: [String: String], element: String) -> [String: String] in
    
        let elements = element.componentsSeparatedByString(":")
        let key = elements[0]
    
        // replace nil with the value you want to use if there is no value        
        let value = (elements.count > 1) ? elements[1] : nil
        aggregate[key] = value
    
        return aggregate
    }
    

    这是一种功能性方法,但您可以使用for 迭代来实现相同的目的。

    【讨论】:

    • var 在参数中? ? 闻起来像 swift 2
    • @GitSyncApp 是的,也许你错过了问题中的“swift2”标签。
    • 当然。但是互联网有点转向 swift 3。这也是减少到 dict 的最佳方法吗?你不是在每次迭代时都创建一个新的字典吗?我真的很好奇。 :)
    • @GitSyncApp 在var 的第二个选项中,我们可以确定只创建了一个字典。该选项在 Swift 3 中不可用。如果我们谈论第一个选项,这完全取决于字典实现的优化程度。在遇到实际性能问题之前,我不会担心这一点。一般来说,我希望有一个接受键值对数组的字典初始值设定项。也许它会与其他字典改进一起出现在 Swift 4 中。
    • 同意。刚才我们在 swift-lang on slack 上得出了同样的结论。这里希望 Swift 4 ?
    【解决方案3】:

    发生这种情况的原因是map 只能返回数组。如果你使用这个方法来解析你的字符串,那么你需要在之后将它转换成字典。

    var newDict = [String:String]()
    for x in astr {
        for (i, j) in x {
            newDict[i] = j
        }
    }
    

    【讨论】:

      【解决方案4】:

      您的代码的当前问题是 map 函数迭代包含 [["key:value"],["key:value"]..] 的数组,然后您再次将其分开。但它会返回["key":"value"],然后您将其添加到您的数组中。

      相反,您可以将elements[0]:elements[1] 直接添加到本地保存的变量中,这将解决您的问题。像

      finalVariable[elements[0]] = elements[1]

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-02
        • 2017-06-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多