Подтвердить что ты не робот

Как совместить два экземпляра словаря в Swift?

Как добавить один Dictionary в другой Dictionary с помощью Swift?

Я использую библиотеку AlamoFire для отправки JSON на REST server.

Словарь 1

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

Словарь 2

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

Как мне объединить два словаря, чтобы создать новый словарь, как показано ниже?

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

Я пробовал dict1 += dict2 но получил ошибку компиляции:

Двоичный оператор '+ =' нельзя применить к двум операндам '[String: AnyObject]'

4b9b3361

Ответ 2

Мне нравится этот подход:

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

Свифт 4 и 5

В Swift 4 Apple предлагает лучший подход для объединения двух словарей:

let dictionary = ["a": 1, "b": 2]
let newKeyValues = ["a": 3, "b": 4]

let keepingCurrent = dictionary.merging(newKeyValues) { (current, _) in current }
// ["b": 2, "a": 1]

let replacingCurrent = dictionary.merging(newKeyValues) { (_, new) in new }
// ["b": 4, "a": 3]

Здесь у вас есть 2 варианта (как и для большинства функций, работающих с контейнерами):

  • merge мутирует существующий словарь
  • merging возвращает новый словарь

Ответ 3

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

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

Swift 4 имеет новую функцию: let parameters = dict1.reduce(into: dict2) { (r, e) in r[e.0] = e.1 }

Очень важно покопаться в стандартной библиотеке: map, reduce, dropFirst, forEach и т.д. Являются основными элементами краткого кода. Функциональные биты - это весело!

Ответ 4

SequenceType.forEach (реализованный Dictionary) предоставляет элегантное решение для добавления элементов словаря в другой словарь.

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

Например

func testMergeDictionaries() {
    let dic1 = [1:"foo"]
    var dic2 = [2:"bar"]

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

    XCTAssertEqual(dic2[1], "foo")
}

Ответ 5

func +=<Key, Value> (lhs: inout [Key: Value], rhs: [Key: Value]) {
    rhs.forEach{ lhs[$0] = $1 }
}

var dic1 = ["test1": 1]

dic1 += ["test2": 2]

dic1  // ["test2": 2, "test1": 1]

Ответ 6

Попробуйте этот подход

    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)

Будет напечатано следующее:

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

}

Надеюсь, что это поможет!

Ответ 7

Мои потребности были разные, я хотел слиться и не ссориться.

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]]

Я надеялся на более простое решение, но это то, чем я закончил. Задача заключалась в переходе от динамической типизации к статической типизации, и я использовал протоколы для решения этой проблемы.

Также стоит отметить, что при использовании синтаксиса словарного литерала вы фактически получаете типы фундамента, которые не подбирают расширения протокола. Я прервал свои усилия, чтобы поддержать их, поскольку я не мог найти легко обосновать единообразие элементов коллекции.

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)")

Ответ 8

Вы можете использовать приведенный ниже код для объединения двух экземпляров словаря в Swift:

extension Dictionary {
    func merge(dict: Dictionary<Key,Value>) -> Dictionary<Key,Value> {
        var mutableCopy = self
        for (key, value) in dict {
            // If both dictionaries have a value for same key, the value of the other dictionary is used.
            mutableCopy[key] = value
        }
        return mutableCopy
    }
}

Ответ 9

Вы используете слово let для объявления словаря, чтобы не вносить изменения в словарь, поскольку он используется для объявления константы.

Измените его на ключевое слово var, и оно будет работать для вас.

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

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

dict1 += dict2

Ответ 10

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


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

var ArrayOfDictionary = [dict1,dict2]


println(ArrayOfDictionary)

Отпечатано

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