SE-0218 — Introduce compactMapValues to Dictionary

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()
1 Like