我正在寻找类型安全的通用版this answer。
这是我正在寻找的方法签名:
extension Dictionary where Value == Optional<T> {
func filterNil() -> <Key, T>
}
有没有办法在Swift 3中表达这个?
修改
我创建带有可选值的词典的动机是我需要这样的东西:
struct User {
var mail: String?
var name: String?
func marshaled() -> [String: Any] {
return [
"mail": mail,
"name": name
].filterNil()
}
}
我更喜欢字典文字来创建一个空字典并手动填充值。
答案 0 :(得分:10)
更新:从 Swift 5 开始,这将是:
let filtered = dict.compactMapValues { $0 }
更新:从 Swift 4 开始,您可以轻松完成
let filtered = dict.filter( { $0.value != nil }).mapValues( { $0! })
如果Dictionary
应该获得currently being discussed
一种compactMapValues
方法,它结合了filter
和mapValues
。
(上一个回答:) 您可以使用与How can I write a function that will unwrap a generic property in swift assuming it is an optional type?和Creating an extension to filter nils from an Array in Swift相同的“技巧”: 定义所有选项符合的协议:
protocol OptionalType {
associatedtype Wrapped
func intoOptional() -> Wrapped?
}
extension Optional : OptionalType {
func intoOptional() -> Wrapped? {
return self
}
}
然后您的字典扩展名可以定义为:
extension Dictionary where Value: OptionalType {
func filterNil() -> [Key: Value.Wrapped] {
var result: [Key: Value.Wrapped] = [:]
for (key, value) in self {
if let unwrappedValue = value.intoOptional() {
result[key] = unwrappedValue
}
}
return result
}
}
示例:
let dict = ["mail": nil, "name": "John Doe"] // Type is [String : String?]
let filtered = dict.filterNil() // Type is [String : String]
print(filtered) // Output: ["name": "John Doe"]