Search code examples
swiftdictionarygenericsswift-extensions

How can I extend dictionaries whose values are dictionaries themselves?


Say I want to extend nested dictionaries with some functionality. Using pseudo-Swift, this is my goal:

extension Dictionary where Value: Dictionary {
    typealias K1 = Key
    typealias K2 = Value.Key
    typealias V  = Value.Value

    subscript(k1: K1, k2: K2) -> V? {
        return self[k1]?[k2]
    }
}

I can not get this to work, though. Type bounds can not be non-protocol types; no protocol that Dictionary implements provides the methods I and types I need to refer to; getting access to the types of generics is cumbersome; and so on. Nothing I tried works out.

What is a solution for this?


Solution

  • One trick (dare I say pattern?) we can use here is to define our own protocol (which we never intend to use anywhere else) which declares all we need and we know Dictionary conforms to, anyway.

    protocol DictionaryProtocol {
        associatedtype Key: Hashable
        associatedtype Value
    
        subscript(key: Key) -> Value? { get set }
    }
    
    extension Dictionary: DictionaryProtocol {}
    
    extension Dictionary where Value: DictionaryProtocol {
        typealias K1 = Key
        typealias K2 = Value.Key
        typealias V  = Value.Value
    
        subscript(k1: K1, k2: K2) -> V? {
            return self[k1]?[k2]
        }
    }
    

    This solution carries over to arrays of arrays, and probably many similar cases.