【问题标题】:How to extract a subset of a swift 3 Dictionary如何提取swift 3字典的子集
【发布时间】:2017-01-04 18:45:49
【问题描述】:

我查看了methods here,但找不到我要找的东西。我是 Swift 的新手。我想根据一组键值从字典中提取一个子集,最好没有循环。

例如,如果我的键 Set 的类型为 Set<String>,并且我有一个类型为 Dictionary<String, CustomObject> 的字典,我想创建一个类型为 Dictionary<String, CustomObject> 的新字典,其中仅包含与字符串集中的键。

我可以看到我可以使用for 循环来执行此操作,方法是初始化一个新的Dictionary<String, CustomObj>(),检查原始字典是否包含集合中每个字符串的值,并将键值对添加到新字典.不过,我想知道是否有更有效/更优雅的方式来做到这一点。

如果有更好的方法来使用键数组来查找子集,我愿意使用字符串数组而不是 Set。

非常感谢!

【问题讨论】:

  • @AntonBronnikov 谢谢,你能澄清一下 - “这样做”是指迭代过程吗?

标签: swift dictionary swift3 nsdictionary


【解决方案1】:

Swift 5 - 你可以很简单地做到这一点:

let subsetDict = originalDict.filter({ mySet.contains($0.key)})

结果是一个新字典,其类型与原始字典相同,但只包含与 mySet 中的键对应的键值对。

【讨论】:

    【解决方案2】:

    你的假设是正确的,有一种更简洁/快速的方式来完成你需要的。

    例如,您可以通过reduce 来实现,这是 Swift 中可用的函数式编程概念:

    let subDict = originalDict.reduce([String: CustomObject]()) {
        guard mySet.contains($1.key) else { return $0 }
        var d = $0
        d[$1.key] = $1.value
        return d
    }
    

    或者,分两步,首先过滤有效元素,然后用过滤后的元素构造回字典:

    let filteredDict = originalDict.filter { mySet.contains($0.key) }
        .reduce([CustomObject]()){ var d = $0; d[$1.key]=$1.value; return d }
    

    forEach也可以用来构造过滤字典:

    var filteredDict = [CustomObject]()
    mySet.forEach { filteredDict[$0] = originalDict[$0] }
    

    ,但是结果会很好,因为它是不可变的:

    let filteredDict: [String:CustomObject] = { 
        var result = [String:CustomObject]()
        mySet.forEach { filteredDict2[$0] = originalDict[$0] }
        return result
    }()
    

    【讨论】:

    • 这可能看起来“swift-ish”但非常无效,因为在每个归约步骤中都会创建一个新字典。比较airspeedvelocity.net/2015/08/03/…。
    • @MartinR 你是对的,我已经添加了一些不应该遇到这个问题的解决方案。顺便说一句,感谢文章链接,非常有见地。
    • 完美,正是我想要的。谢谢!
    【解决方案3】:

    虚拟类型:

    struct CustomObject {
        let foo: Int
        init(_ foo: Int) { self.foo = foo }
    }
    

    如果您想根据一组给定的键以“相交”方式改变原始字典(而不是创建新字典):

    let keySet = Set(["foo", "baz"])
    var dict = ["foo": CustomObject(1), "bar": CustomObject(2),
                "baz": CustomObject(3), "bax": CustomObject(4)]
    
    Set(dict.keys).subtracting(keySet).forEach { dict.removeValue(forKey: $0) }
    
    print(dict) // ["foo": CustomObject(foo: 1), "baz": CustomObject(foo: 3)]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-06
      • 1970-01-01
      • 2011-07-18
      • 2017-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多