Swift: Merging Dictionaries

“Erica, Is there a method to merge the content of a dictionary in another? I mean, without using an NSMutableDictionary”

Here’s what I went with. Make sure the updated dictionary is mutable.

extension Dictionary {
    mutating func unionInPlace(
        dictionary: Dictionary<Key, Value>) {
        for (key, value) in dictionary {
            self[key] = value
        }
    }
}

I chose to use Dictionary<Key, Value> over [Key:Value] to mimic the style in the standard library although I’m not really wedded to this. I also changed my initial name from union to unionByOverwriting to indicate that all updates perform in-place replacements.

Update:

extension Dictionary {
    mutating func unionInPlace(
        dictionary: Dictionary<Key, Value>) {
            for (key, value) in dictionary {
                self[key] = value
            }
    }
    
    // Thanks Airspeed Velocity
    mutating func unionInPlace<S: SequenceType where 
        S.Generator.Element == (Key,Value)>(sequence: S) {
        for (key, value) in sequence {
            self[key] = value
        }
    }
}

5 Comments

  • You can also find an implementation of the merge method within the Dollar.swift library here:
    https://github.com/ankurp/Dollar.swift/blob/master/Cent/Cent/Dictionary.swift

    When using the Dollar library it should be automatically available – or you just copy the implementation, which will of course be always up to date, even if Swift changes over time.

  • When defining this in Swift 3.0 for Sequence, like this:

    mutating func merge(_ other: S) where S.Iterator.Element == (Key, Value) {
    for (key, value) in other {
    self[key] = value
    }
    }

    when trying to call merge on two same-type dictionaries I get an error that “Generic parameter S could not be inferred”. What has changed in Swift 3.0?

  • I got it…instead of (Key, Value) tuple I’d have to use one with explicitly declared types like (key: Key, value: Value). When in Dictionary extension it could be just == Element I guess

    • Do you have an example on how it looks like now on swift 3?

      • I do not have a policy of updating older posts