¿Cómo agrego uno Dictionary
a otro Dictionary
usando Swift
?
Estoy usando la AlamoFire
biblioteca para enviar una JSON
a una REST server
.
Diccionario 1
var dict1: [String: AnyObject] = [
kFacebook: [
kToken: token
]
]
Diccionario 2
var dict2: [String: AnyObject] = [
kRequest: [
kTargetUserId: userId
]
]
¿Cómo combino los dos diccionarios para crear un nuevo diccionario como se muestra a continuación?
let parameters: [String: AnyObject] = [
kFacebook: [
kToken: token
],
kRequest: [
kTargetUserId: userId
]
]
Lo intenté dict1 += dict2
pero obtuve un error de compilación:
El operador binario '+ =' no se puede aplicar a dos operandos '[String: AnyObject]'
Respuestas:
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)
Consulte el increíble proyecto Dollar & Cent https://github.com/ankurp/Cent/blob/master/Sources/Dictionary.swift
fuente
extension
para tener estofunction
disponible en cualquier lugar de mi código? ¡Lo siento, soy un novato![Key: Any]
)Dictionary
tiene sus propias funciones de combinación. Consulte stackoverflow.com/a/43615143/971329 .Amo este enfoque:
dicFrom.forEach { (key, value) in dicTo[key] = value }
Swift 4 y 5
Con Swift 4, Apple presenta un mejor enfoque para fusionar dos diccionarios:
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]
Aquí tiene 2 opciones (como con la mayoría de las funciones que operan en contenedores):
merge
muta un diccionario existentemerging
devuelve un nuevo diccionariofuente
Para Swift> = 2.2:
let parameters = dict1.reduce(dict2) { r, e in var r = r; r[e.0] = e.1; return r }
Para Swift <2.2:
let parameters = dict1.reduce(dict2) { (var r, e) in r[e.0] = e.1; return r }
Swift 4 tiene una nueva función:
let parameters = dict1.reduce(into: dict2) { (r, e) in r[e.0] = e.1 }
Es muy importante que cavar alrededor de la biblioteca estándar:
map
,reduce
,dropFirst
,forEach
etc, son alimentos básicos de la escueta código. ¡Los bits funcionales son divertidos!fuente
SequenceType.forEach
(implementado porDictionary
) proporciona una solución elegante para agregar elementos de un diccionario a otro diccionario.dic1.forEach { dic2[$0] = $1 }
Por ejemplo
func testMergeDictionaries() { let dic1 = [1:"foo"] var dic2 = [2:"bar"] dic1.forEach { dic2[$0] = $1 } XCTAssertEqual(dic2[1], "foo") }
fuente
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]
fuente
Podemos fusionar diccionarios de una mejor manera usando merge keyword
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]
fuente
Mis necesidades eran diferentes, quería fusionarme y no golpear.
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]]
Esperaba una solución más simple, pero esto es con lo que terminé. El desafío consistía en pasar de la escritura dinámica a la escritura estática, y utilicé protocolos para resolver esto.
También es digno de mención que cuando usa la sintaxis literal del diccionario, en realidad obtiene los tipos de base, que no recogen las extensiones de protocolo. Aborté mis esfuerzos para apoyarlos ya que no pude encontrar una manera fácil de validar la uniformidad de los elementos de la colección.
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)")
fuente
Pruebe este enfoque
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)
Imprimirá lo siguiente:
}
Espero eso ayude !!
fuente
Puede usar el siguiente código para combinar dos instancias de diccionario en 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 } }
fuente
Está utilizando la palabra clave let para declarar el diccionario, por lo que no puede realizar cambios en su diccionario, ya que se utiliza para declarar constante.
Cámbielo a la palabra clave var, entonces funcionará para usted.
var dict1: [String: AnyObject] = [ kFacebook: [ kToken: token ] ] var dict2: [String: AnyObject] = [ kRequest: [ kTargetUserId: userId ] ] dict1 += dict2
fuente