Las matrices en Swift admiten el operador + = para agregar el contenido de una matriz a otra. ¿Hay una manera fácil de hacer eso para un diccionario?
p.ej:
var dict1 = ["a" : "foo"]
var dict2 = ["b" : "bar"]
var combinedDict = ... (some way of combining dict1 & dict2 without looping)
dictionary
swift
rustyshelf
fuente
fuente
fromDict.forEach {intoDict[$0] = $1}
Respuestas:
Puede definir
+=
operador paraDictionary
, por ejemplo,fuente
@assignment
yreturn
, ya estás mutando a la izquierda. Editar: en realidad, aunque no obtengo errores, creo que@assignment
debería quedarme.func +=<K, V> (inout left: [K : V], right: [K : V]) { for (k, v) in right { left[k] = v } }
public static func +=(lhs: inout [Key: Value], rhs: [Key: Value]) { rhs.forEach({ lhs[$0] = $1}) }
En Swift 4, uno debe usar
merging(_:uniquingKeysWith:)
:Ejemplo:
fuente
[NSMutableDictionary addEntriesFromDictionary:]
.Qué tal si
Eso agrega todas las claves y valores de dict2 en dict1.
fuente
Closure tuple parameter '(key: _, value: _)' does not support destructuring
(al menos en el momento de escribir esto). Sería necesario reestructurar el cierre de acuerdo con [esta respuesta de stackoverflow] ( stackoverflow.com/questions/44945967/… ):Actualmente, mirando la Referencia de la Biblioteca Estándar de Swift para Diccionario, no hay forma de actualizar fácilmente un diccionario con otro.
Puedes escribir una extensión para hacerlo
fuente
Swift 4 proporciona
merging(_:uniquingKeysWith:)
, así que para su caso:El cierre abreviado regresa
$1
, por lo tanto, el valor de dict2 se usará cuando haya un conflicto con las claves.fuente
- (void)addEntriesFromDictionary:(NSDictionary<KeyType, ObjectType> *)otherDictionary;
. Con respecto a qué hacer con los duplicados, establece que: "Si ambos diccionarios contienen la misma clave, el objeto de valor anterior del diccionario receptor para esa clave se envía un mensaje de liberación, y el nuevo objeto de valor ocupa su lugar". la versión Swift, o en combinación (_: uniquingKeysWith :), que devuelve el segundo valor$1
, es lo mismo que lo queaddEntriesFromDictionary
hace.No está integrado en la biblioteca Swift, pero puede agregar lo que desee con la sobrecarga del operador, por ejemplo:
Esto sobrecarga al
+
operador de Diccionarios que ahora puede usar para agregar diccionarios con el+
operador, por ejemplo:fuente
map
y soltar el primerfor (k, v)...
ciclo si declara elleft
parámetro comovar
y luego simplemente copia los valoresright
en él.+
operador infijo.+
sobrecarga del operador tampoco es un métodoDictionary
, es una función simple. Los cambios que realice en unleft
parámetro variable no serían visibles fuera de la función.Swift 3:
fuente
func merged(with dictionary: Dictionary<Key,Value>) -> Dictionary<Key,Value> {
var copy = self
dictionary.forEach { copy.updateValue($1, forKey: $0) }
return copy
}
Swift 2.0
fuente
union
función tiene el valor pasado a ser avar
, lo que significa que el diccionario copiado puede ser mutado. Es un poco más limpio quefunc union(dictionary: Dictionary) -> Dictionary { var dict2 = dictionary; dict2.unionInPlace(self); return dict2 }
, aunque solo sea por una línea.var dictionary = dictionary
. Desde aquí: github.com/apple/swift-evolution/blob/master/proposals/…<Key, Value>
a esasDictionary
s.Inmutable
Prefiero combinar / unir diccionarios inmutables con el
+
operador, así que lo implementé como:Mudable
fuente
right.reduce(left)
, al menos ese es el comportamiento esperado de la OMI (y es el comportamiento de tu segundo ejemplo), es decir.["A":1] + ["A":2]
debería salir["A":2]
No es necesario tener extensiones de diccionario ahora. El diccionario Swift (Xcode 9.0+) tiene una funcionalidad para esto. Echa un vistazo aquí . A continuación se muestra un ejemplo de cómo usarlo.
fuente
oldDictionary.merge(newDictionary) { $1 }
Una variante más legible usando una extensión.
fuente
Puedes probar esto
fuente
También puede usar reducir para fusionarlos. Prueba esto en el patio de recreo
fuente
d
yp
?Recomiendo la Biblioteca SwifterSwift . Sin embargo, si no desea utilizar toda la biblioteca y todas sus excelentes adiciones, puede hacer uso de su extensión de Diccionario:
Swift 3+
fuente
Puede iterar sobre las combinaciones de valores clave del valor que desea combinar y agregarlas a través del método updateValue (forKey :):
Ahora todos los valores de dictionaryTwo se agregaron a dictionaryOne.
fuente
Lo mismo que la respuesta de @ farhadf pero adoptada para Swift 3:
fuente
Swift 3, extensión del diccionario:
fuente
Algunas sobrecargas aún más optimizadas para Swift 4:
fuente
Puede agregar una
Dictionary
extensión como esta:Entonces el uso es tan simple como el siguiente:
Si prefiere un marco que también incluya algunas características más útiles, entonces consulte HandySwift . Simplemente impórtelo a su proyecto y puede usar el código anterior sin agregar ninguna extensión al proyecto usted mismo.
fuente
Ya no hay necesidad de extensión ni ninguna función adicional. Puedes escribir así:
fuente
Puedes usar,
fuente
Puede usar la función bridgeToObjectiveC () para hacer que el diccionario sea un NSDictionary.
Será como el siguiente:
Luego puede convertir el NSDictionary (combinar) o hacer lo que sea.
fuente
El resultado es un NSMutableDictionary, no un diccionario de tipo Swift, pero la sintaxis para usarlo es la misma (
out["a"] == 1
en este caso), por lo que solo tendría un problema si está utilizando un código de terceros que espera un diccionario Swift, o realmente Necesito el tipo de comprobación.La respuesta corta aquí es que realmente tienes que hacer un bucle. Incluso si no lo está ingresando explícitamente, eso es lo que hará el método al que está llamando (addEntriesFromDictionary: aquí). Sugeriría que si no está claro por qué ese sería el caso, debería considerar cómo fusionaría los nodos de las hojas de dos árboles B.
Si realmente necesitas un tipo de diccionario nativo Swift a cambio, te sugiero:
La desventaja de este enfoque es que el índice del diccionario, como sea que esté hecho, puede reconstruirse varias veces en el ciclo, por lo que en la práctica es aproximadamente 10 veces más lento que el enfoque NSMutableDictionary.
fuente
Todas estas respuestas son complicadas. Esta es mi solución para swift 2.2:
fuente
Mis necesidades eran diferentes, necesitaba fusionar conjuntos de datos anidados incompletos sin tropezar.
Esto fue más difícil de lo que quería que fuera. El desafío estaba en el mapeo del tipeo dinámico al tipeo estático, y usé protocolos para resolver esto.
También es digno de mención que cuando usa la sintaxis literal del diccionario, en realidad obtiene los tipos básicos, que no recogen las extensiones de protocolo. Aborté mis esfuerzos para apoyarlos, ya que no pude encontrar una forma fácil de validar la uniformidad de los elementos de la colección.
fuente
Swift 2.2
fuente
Solo usaría la biblioteca Dollar .
https://github.com/ankurp/Dollar/#merge---merge-1
Fusiona todos los diccionarios y este último anula el valor en una clave determinada
fuente
Aquí hay una buena extensión que escribí ...
usar:
Entonces, dict1 se modificará a
fuente