Swift: how to combine two Dictionary instances?

How do I append one [Dictionary] to another [Dictionary] using Swift?

I am using the AlamoFire library to send a JSON to a REST server.

  • generate MDM certificate
  • Select UITableView's row when clicking on UISwitch
  • Set default iOS web clip icon title?
  • Parse geopoint swift not getting current location
  • How to pass a value to parent view controller?
  • Make XCUIElement perform 3D touch for Automate UITest?
  • Dictionary 1

    let dict1: [String: AnyObject] = [
                kFacebook: [
                    kToken: token
                ]
            ]
    

    Dictionary 2

    let dict2: [String: AnyObject] = [
            kRequest: [
                kTargetUserId: userId
            ]
        ]
    

    How do I combine the two dictionaries to achieve like below?

    let parameters: [String: AnyObject] = [
            kFacebook: [
                kToken: token
            ],
            kRequest: [
                kTargetUserId: userId
            ]
        ]
    

    I have tried dict1 += dict2 but got a compile error.

    Thanks in advance!

    9 Solutions Collect From Internet About “Swift: how to combine two Dictionary instances?”

    var d1 = ["a": "b"]
    var d2 = ["c": "e"]
    
    extension Dictionary {
        mutating func merge(dict: [Key: Value]){
            for (k, v) in dict {
                updateValue(v, forKey: k)
            }
        }
    }
    
    d1.merge(d2)
    

    Refer to the awesome Dollar & Cent project
    https://github.com/ankurp/Cent/blob/master/Sources/Dictionary.swift

    For Swift >= 2.2:
    let parameters = dict1.reduce(dict2) { r, e in var r = r; r[e.0] = e.1; return r }

    For Swift < 2.2:
    let parameters = dict1.reduce(dict2) { (var r, e) in r[e.0] = e.1; return r }

    It’s really important to dig around the standard library: map, reduce, dropFirst, forEach etc. are staples of terse code. The functional bits are fun!

    SequenceType.forEach (implemented by Dictionary) provides an elegant solution to add a dictionary’s elements to another dictionary.

    dic1.forEach { dic2[$0] = $1 }
    

    For example

    func testMergeDictionaries() {
        let dic1 = [1:"foo"]
        var dic2 = [2:"bar"]
    
        dic1.forEach { dic2[$0] = $1 }
    
        XCTAssertEqual(dic2[1], "foo")
    }
    
    func +=<Key, Value> (inout lhs: [Key: Value], rhs: [Key: Value]) {
        rhs.forEach{ lhs[$0] = $1 }
    }
    
    var dic1 = ["test1": 1]
    
    dic1 += ["test2": 2]
    
    dic1  // ["test2": 2, "test1": 1]
    

    I love this approach:

    dicFrom.forEach { (key, value) in dicTo[key] = value }

    Try This Approach

        let dict1: [String: AnyObject] = ["kFacebook": ["kToken": "token"]]
        let dict2: [String: AnyObject] = ["kRequest": ["kTargetUserId": "userId"]]
    
        var combinedAttributes : NSMutableDictionary!
    
        combinedAttributes = NSMutableDictionary(dictionary: dict1)
    
        combinedAttributes.addEntriesFromDictionary(dict2)
    
        println(combinedAttributes)
    

    It will Print Following :

    {
    kFacebook =     {
        kToken = token;
    };
    kRequest =     {
        kTargetUserId = userId;
    };
    

    }

    Hope it helps !!

    My needs were different, I wanted to merge and not clobber.

    merging:
        ["b": [1, 2], "s": Set([5, 6]), "a": 1, "d": ["x": 2]]
    with
        ["b": [3, 4], "s": Set([6, 7]), "a": 2, "d": ["y": 4]]
    yields:
        ["b": [1, 2, 3, 4], "s": Set([5, 6, 7]), "a": 2, "d": ["y": 4, "x": 2]]
    

    I was hoping for a simpler solution, but this is what I ended up with. The challenge was in hopping from dynamic typing to static typing, and I used protocols to solve this.

    Also worthy of note is that when you use the dictionary literal syntax, you actually get the foundation types, which do not pick up the protocol extensions. I aborted my efforts to support those as I couldn’t find an easy to to validate the uniformity of the collection elements.

    import UIKit
    
    
    private protocol Mergable {
        func mergeWithSame<T>(right: T) -> T?
    }
    
    
    
    public extension Dictionary {
    
        /**
        Merge Dictionaries
    
        - Parameter left: Dictionary to update
        - Parameter right:  Source dictionary with values to be merged
    
        - Returns: Merged dictionay
        */
    
    
        func merge(right:Dictionary) -> Dictionary {
            var merged = self
            for (k, rv) in right {
    
                // case of existing left value
                if let lv = self[k] {
    
                    if let lv = lv as? Mergable where lv.dynamicType == rv.dynamicType {
                        let m = lv.mergeWithSame(rv)
                        merged[k] = m
                    }
    
                    else if lv is Mergable {
                        assert(false, "Expected common type for matching keys!")
                    }
    
                    else if !(lv is Mergable), let _ = lv as? NSArray {
                        assert(false, "Dictionary literals use incompatible Foundation Types")
                    }
    
                    else if !(lv is Mergable), let _ = lv as? NSDictionary {
                        assert(false, "Dictionary literals use incompatible Foundation Types")
                    }
    
                    else {
                        merged[k] = rv
                    }
                }
    
                    // case of no existing value
                else {
                    merged[k] = rv
                }
            }
    
            return merged
        }
    }
    
    
    
    
    extension Array: Mergable {
    
        func mergeWithSame<T>(right: T) -> T? {
    
            if let right = right as? Array {
                return (self + right) as? T
            }
    
            assert(false)
            return nil
        }
    }
    
    
    extension Dictionary: Mergable {
    
        func mergeWithSame<T>(right: T) -> T? {
    
            if let right = right as? Dictionary {
                return self.merge(right) as? T
            }
    
            assert(false)
            return nil
        }
    }
    
    
    extension Set: Mergable {
    
        func mergeWithSame<T>(right: T) -> T? {
    
            if let right = right as? Set {
                return self.union(right) as? T
            }
    
            assert(false)
            return nil
        }
    }
    
    
    
    var dsa12 = Dictionary<String, Any>()
    dsa12["a"] = 1
    dsa12["b"] = [1, 2]
    dsa12["s"] = Set([5, 6])
    dsa12["d"] = ["c":5, "x": 2]
    
    
    var dsa34 = Dictionary<String, Any>()
    dsa34["a"] = 2
    dsa34["b"] = [3, 4]
    dsa34["s"] = Set([6, 7])
    dsa34["d"] = ["c":-5, "y": 4]
    
    
    //let dsa2 = ["a": 1, "b":a34]
    let mdsa3 = dsa12.merge(dsa34)
    print("merging:\n\t\(dsa12)\nwith\n\t\(dsa34) \nyields: \n\t\(mdsa3)")
    

    You are using let keyword to declare the dictionary so you can’t make the changes to your dictionary as it is used to declare constant.

    Change it to var keyword then it will work for you.

    var dict1: [String: AnyObject] = [
                kFacebook: [
                    kToken: token
                ]
            ]
    
    var dict2: [String: AnyObject] = [
            kRequest: [
                kTargetUserId: userId
            ]
        ]
    
    dict1 += dict2
    
    let dict1: [String: AnyObject] = [
        "kFacebook": [
            "kToken": "token"
        ]
    ]
    
    
    let dict2: [String: AnyObject] = [
        "kRequest": [
            "kTargetUserId": "userId"
        ]
    ]
    
    var ArrayOfDictionary = [dict1,dict2]
    
    
    println(ArrayOfDictionary)
    

    This printed

    [[kFacebook: {
        kToken = token;
    }], [kRequest: {
        kTargetUserId = userId;
    }]]