如何提取swift 3 Dictionary的子集

时间:2017-01-04 18:45:50

标签: swift dictionary swift3 nsdictionary

我查看了methods here,但我找不到我想要的东西。我是斯威夫特的新人。我想基于一组键值从字典中提取子集,最好没有循环。

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

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

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

非常感谢!

3 个答案:

答案 0 :(得分:1)

您的假设是正确的,有一种更简洁/快捷的方式来实现您的需要。

例如,您可以通过let subDict = originalDict.reduce([String: CustomObject]()) { guard mySet.contains($1.key) else { return $0 } var d = $0 d[$1.key] = $1.value return d } 来实现,这是Swift中提供的函数式编程概念:

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
}()

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

item size    weight
---- ----    ------
 a   small     1.2
 a   medium    2.2
 b   medium    1.6
 c   small     1.0
 c   medium    1.5
 c   large     2.0

答案 1 :(得分:1)

Swift 5 -您可以非常简单地执行此操作:

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

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

答案 2 :(得分:0)

虚拟类型:

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)]