Wie anhängen ich eine Dictionary
an eine andere Dictionary
Verwendung Swift
?
Ich benutze die AlamoFire
Bibliothek, um a JSON
an a zu senden REST server
.
Wörterbuch 1
var dict1: [String: AnyObject] = [
kFacebook: [
kToken: token
]
]
Wörterbuch 2
var dict2: [String: AnyObject] = [
kRequest: [
kTargetUserId: userId
]
]
Wie kombiniere ich die beiden Wörterbücher, um ein neues Wörterbuch zu erstellen, wie unten gezeigt?
let parameters: [String: AnyObject] = [
kFacebook: [
kToken: token
],
kRequest: [
kTargetUserId: userId
]
]
Ich habe es versucht, dict1 += dict2
aber einen Kompilierungsfehler erhalten:
Der Binäroperator '+ =' kann nicht auf zwei '[String: AnyObject]' - Operanden angewendet werden
Antworten:
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)
Weitere Informationen finden Sie im großartigen Dollar & Cent-Projekt https://github.com/ankurp/Cent/blob/master/Sources/Dictionary.swift
quelle
extension
, umfunction
es irgendwo in meinem Code verfügbar zu haben ? Entschuldigung, ich bin ein Noob![Key: Any]
)Dictionary
eigene Zusammenführungsfunktionen verfügt. Siehe stackoverflow.com/a/43615143/971329 .Ich liebe diesen Ansatz:
dicFrom.forEach { (key, value) in dicTo[key] = value }
Swift 4 und 5
Mit Swift 4 führt Apple einen besseren Ansatz zum Zusammenführen von zwei Wörterbüchern ein:
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]
Sie haben hier zwei Möglichkeiten (wie bei den meisten Funktionen, die mit Containern ausgeführt werden):
merge
mutiert ein vorhandenes Wörterbuchmerging
gibt ein neues Wörterbuch zurückquelle
Für Swift> = 2.2:
let parameters = dict1.reduce(dict2) { r, e in var r = r; r[e.0] = e.1; return r }
Für Swift <2.2:
let parameters = dict1.reduce(dict2) { (var r, e) in r[e.0] = e.1; return r }
Swift 4 hat eine neue Funktion:
let parameters = dict1.reduce(into: dict2) { (r, e) in r[e.0] = e.1 }
Es ist wirklich wichtig , um die Standard - Bibliothek wühlen:
map
,reduce
,dropFirst
,forEach
usw. sind Heftklammern des lapidaren Code. Die funktionalen Teile machen Spaß!quelle
SequenceType.forEach
(implementiert vonDictionary
) bietet eine elegante Lösung, um die Elemente eines Wörterbuchs einem anderen Wörterbuch hinzuzufügen.dic1.forEach { dic2[$0] = $1 }
Zum Beispiel
func testMergeDictionaries() { let dic1 = [1:"foo"] var dic2 = [2:"bar"] dic1.forEach { dic2[$0] = $1 } XCTAssertEqual(dic2[1], "foo") }
quelle
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]
quelle
Mit dem Schlüsselwort merge können wir Wörterbücher besser zusammenführen
var dictionary = ["a": 1, "b": 2] /// Keeping existing value for key "a": dictionary.merge(["a": 3, "c": 4]) { (current, _) in current } // ["b": 2, "a": 1, "c": 4]
quelle
Meine Bedürfnisse waren anders, ich wollte verschmelzen und nicht überfallen.
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]]
Ich hatte auf eine einfachere Lösung gehofft, aber damit bin ich gelandet. Die Herausforderung bestand darin, von der dynamischen zur statischen Typisierung zu wechseln, und ich habe Protokolle verwendet, um dies zu lösen.
Bemerkenswert ist auch, dass Sie bei Verwendung der Wörterbuch-Literal-Syntax tatsächlich die Grundlagentypen erhalten, die die Protokollerweiterungen nicht übernehmen. Ich habe meine Bemühungen, diese zu unterstützen, abgebrochen, da ich keine einfache Möglichkeit fand, die Einheitlichkeit der Sammlungselemente zu überprüfen.
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)")
quelle
Versuchen Sie diesen Ansatz
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)
Es wird Folgendes gedruckt:
}}
Ich hoffe es hilft !!
quelle
Mit dem folgenden Code können Sie zwei Wörterbuchinstanzen in Swift kombinieren:
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 } }
quelle
Sie verwenden das Schlüsselwort let, um das Wörterbuch zu deklarieren, sodass Sie keine Änderungen an Ihrem Wörterbuch vornehmen können, da es zum Deklarieren von Konstanten verwendet wird.
Ändern Sie es in das Schlüsselwort var, dann funktioniert es für Sie.
var dict1: [String: AnyObject] = [ kFacebook: [ kToken: token ] ] var dict2: [String: AnyObject] = [ kRequest: [ kTargetUserId: userId ] ] dict1 += dict2
quelle