FWIW, it could be expressed if we introduced something along the lines of the Unwrappable
protocol discussed here: Introducing `Unwrappable`, a biased unwrapping protocol. A protocol like that should be debated on its own merit of course, but it's worth pointing out that it would enable algorithms like these to work over types other than Optional
(such as Result
).
protocol Unwrappable {
associatedtype Wrapped
func unwrap() -> Wrapped?
}
extension Optional: Unwrappable {
func unwrap() -> Wrapped? {
return self
}
}
extension Array where Element: Unwrappable {
func compact() -> [Element.Wrapped] {
return compactMap { $0.unwrap() }
}
}
extension Dictionary where Value: Unwrappable {
func comactValues() -> [Key: Value.Wrapped] {
let result = lazy.compactMap { keyValue -> (Key, Value.Wrapped)? in
guard let value = keyValue.value.unwrap() else {
return nil
}
return (keyValue.key, value)
}
return Dictionary<Key, Value.Wrapped>(uniqueKeysWithValues: result)
}
}
let array: [Int?] = [42, nil, 42]
let compactArray = array.compact()
let dictionary: [Int: String?] = [42: "42", 43: nil, 44: "44"]
let compactDictionary = dictionary.comactValues()