我查看了methods here,但我找不到我想要的东西。我是斯威夫特的新人。我想基于一组键值从字典中提取子集,最好没有循环。
例如,如果我的密钥集类型为Set<String>
且我有一个类型为Dictionary<String, CustomObject>
的字典,我想创建一个类型为Dictionary<String, CustomObject>
的新字典,其仅包含与字符串集中的键关联的键值对。
我可以看到我可以通过for
循环执行此操作,方法是初始化一个新的Dictionary<String, CustomObj>()
,检查原始Dictionary是否包含集合中每个String的值,并添加键值对到新词典。我想知道是否有一种更有效/更优雅的方式来做到这一点。
如果有更好的方法可以使用数组键,我可以使用数组字符串而不是Set来查找子集。
非常感谢!
答案 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)]