【问题标题】:Swift dictionary comprehensionSwift 字典理解
【发布时间】:2015-11-08 10:10:34
【问题描述】:

其他语言(例如 Python)允许您使用字典推导从数组中生成字典,但我还没有弄清楚如何在 Swift 中做到这一点。我以为我可以使用这样的东西,但它无法编译:

let x = ["a","b","c"]
let y = x.map( { ($0:"x") })
// expected y to be ["a":"x", "b":"x", "c":"x"]

在swift中从数组生成字典的正确方法是什么?

【问题讨论】:

    标签: swift dictionary-comprehension


    【解决方案1】:

    map 方法只是将数组的每个元素转换为一个新元素。然而,结果仍然是一个数组。要将数组转换为字典,您可以使用reduce 方法。

    let x = ["a","b","c"]
    let y = x.reduce([String: String]()) { (var dict, arrayElem) in
        dict[arrayElem] = "this is the value for \(arrayElem)"
        return dict
    }
    

    这将生成字典

    ["a": "this is the value for a",
     "b": "this is the value for b",
     "c": "this is the value for c"]
    

    一些解释:reduce 的第一个参数是初始值,在这种情况下是空字典[String: String]()reduce 的第二个参数是一个回调,用于将数组的每个元素组合成当前值。在这种情况下,当前值是字典,我们在其中为每个数组元素定义一个新的键和值。修改后的字典也需要在回调中返回。


    更新:由于reduce 方法对于大型数组(请参阅 cmets)可能会占用大量内存,因此您还可以定义类似于以下 sn-p 的自定义理解函数。

    func dictionaryComprehension<T,K,V>(array: [T], map: (T) -> (key: K, value: V)?) -> [K: V] {
        var dict = [K: V]()
        for element in array {
            if let (key, value) = map(element) {
                dict[key] = value
            }
        }
        return dict
    }
    

    调用该函数如下所示。

    let x = ["a","b","c"]
    let y = dictionaryComprehension(x) { (element) -> (key: String, value: String)? in
        return (key: element, value: "this is the value for \(element)")
    }
    

    更新 2:除了自定义函数,您还可以在 Array 上定义扩展,这将使代码更易于重用。

    extension Array {
        func toDict<K,V>(map: (T) -> (key: K, value: V)?) -> [K: V] {
            var dict = [K: V]()
            for element in self {
                if let (key, value) = map(element) {
                    dict[key] = value
                }
            }
            return dict
        }
    }
    

    调用上面的代码看起来像这样。

    let x = ["a","b","c"]
    let y = x.toDict { (element) -> (key: String, value: String)? in
        return (key: element, value: "this is the value for \(element)")
    }
    

    【讨论】:

    • 请注意,这会在每个缩减步骤中创建一个新字典。如果应用于 large 数组,这可能是一个性能问题。
    • @MartinR 是不是因为字典是按值传递给回调的,因为它内部是一个结构体?
    • 是的,完全正确。另请参阅此评论:stackoverflow.com/questions/24116271/….
    • 在 Swift 4 中,Dictionary 有一个采用元组的初始化器。如果已知元组具有不同的键,请使用Dictionary(uniqueKeysWithValues: x.map { ($0, "x") })。否则,如果可能存在密钥冲突,请使用例如 Dictionary(x.map { ($0, "x") }, uniquingKeysWith: { (first,_) in first } )
    猜你喜欢
    • 1970-01-01
    • 2021-07-24
    • 2016-09-03
    • 1970-01-01
    • 2016-03-14
    • 1970-01-01
    • 2018-01-21
    • 1970-01-01
    • 2019-11-26
    相关资源
    最近更新 更多