Les tableaux dans Swift prennent en charge l'opérateur + = pour ajouter le contenu d'un tableau à un autre. Existe-t-il un moyen simple de le faire pour un dictionnaire?
par exemple:
var dict1 = ["a" : "foo"]
var dict2 = ["b" : "bar"]
var combinedDict = ... (some way of combining dict1 & dict2 without looping)
dictionary
swift
rouille
la source
la source
fromDict.forEach {intoDict[$0] = $1}
Réponses:
Vous pouvez définir un
+=
opérateur pourDictionary
, par exemple,la source
@assignment
etreturn
, vous êtes déjà en train de muter à gauche. Edit: en fait, même si je n'obtiens aucune erreur, je pense que cela@assignment
devrait rester.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}) }
Dans Swift 4, il faut utiliser
merging(_:uniquingKeysWith:)
:Exemple:
la source
[NSMutableDictionary addEntriesFromDictionary:]
.Que diriez-vous
Cela ajoute toutes les clés et valeurs de dict2 dans dict1.
la source
Closure tuple parameter '(key: _, value: _)' does not support destructuring
(du moins au moment de la rédaction de cet article). Il faudrait restructurer la fermeture en fonction de [cette réponse stackoverflow] ( stackoverflow.com/questions/44945967/... ):Actuellement, en regardant la référence de la bibliothèque standard Swift pour le dictionnaire, il n'y a aucun moyen de mettre à jour facilement un dictionnaire avec un autre.
Vous pouvez écrire une extension pour le faire
la source
Swift 4 fournit
merging(_:uniquingKeysWith:)
, donc pour votre cas:La fermeture abrégée retourne
$1
, donc la valeur de dict2 sera utilisée en cas de conflit avec les clés.la source
- (void)addEntriesFromDictionary:(NSDictionary<KeyType, ObjectType> *)otherDictionary;
. En ce qui concerne ce qu'il faut faire avec les doublons, il indique que: "Si les deux dictionnaires contiennent la même clé, l'objet de valeur précédent du dictionnaire de réception pour cette clé reçoit un message de libération et le nouvel objet de valeur prend sa place.", Donc dans la version Swift, ou en merge (_: uniquingKeysWith :), renvoyant la deuxième valeur$1
, est identique à ce queaddEntriesFromDictionary
fait.Il n'est pas intégré à la bibliothèque Swift mais vous pouvez ajouter ce que vous voulez avec la surcharge d'opérateurs, par exemple:
Cela surcharge l'
+
opérateur pour les dictionnaires que vous pouvez maintenant utiliser pour ajouter des dictionnaires avec l'+
opérateur, par exemple:la source
map
et supprimer la premièrefor (k, v)...
boucle si vous déclarez leleft
paramètre commevar
, puis copiez simplement les valeurs à partir deright
celui-ci.+
opérateur infixe.+
surcharge d'opérateurs n'est pas une méthode non plusDictionary
, c'est une fonction simple. Les modifications que vous apportez à unleft
paramètre variable ne seraient pas visibles en dehors de la fonction.Swift 3:
la source
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
la source
union
fonction a la valeur qui lui est passéevar
, ce qui signifie que le dictionnaire copié peut être muté. C'est un peu plus propre quefunc union(dictionary: Dictionary) -> Dictionary { var dict2 = dictionary; dict2.unionInPlace(self); return dict2 }
, ne serait-ce que par une ligne.var dictionary = dictionary
. De là: github.com/apple/swift-evolution/blob/master/proposals<Key, Value>
à cesDictionary
s.Immuable
Je préfère combiner / unir des dictionnaires immuables avec un
+
opérateur, donc je l'ai implémenté comme:Mutable
la source
right.reduce(left)
, au moins c'est le comportement attendu imo (et c'est le comportement de votre deuxième exemple) - ie.["A":1] + ["A":2]
devrait sortir["A":2]
Pas besoin d'avoir des extensions de dictionnaire maintenant. Le dictionnaire Swift (Xcode 9.0+) a une fonctionnalité pour cela. Jetez un œil ici . Ci-dessous, voici un exemple d'utilisation
la source
oldDictionary.merge(newDictionary) { $1 }
Une variante plus lisible utilisant une extension.
la source
Tu peux essayer ça
la source
Vous pouvez également utiliser réduire pour les fusionner. Essayez ceci dans la cour de récréation
la source
d
etp
?Je recommande la bibliothèque SwifterSwift . Cependant, si vous ne souhaitez pas utiliser toute la bibliothèque et tous ses excellents ajouts, vous pouvez simplement utiliser leur extension de Dictionary:
Swift 3+
la source
Vous pouvez parcourir les combinaisons de valeurs clés par rapport à la valeur que vous souhaitez fusionner et les ajouter via la méthode updateValue (forKey :):
Maintenant, toutes les valeurs de dictionaryTwo ont été ajoutées à dictionaryOne.
la source
Identique à la réponse de @ farhadf mais adoptée pour Swift 3:
la source
Swift 3, extension de dictionnaire:
la source
Quelques surcharges encore plus simplifiées pour Swift 4:
la source
Vous pouvez ajouter une
Dictionary
extension comme celle-ci:Ensuite, l' utilisation est aussi simple que ce qui suit:
Si vous préférez un cadre qui comprend également quelques fonctionnalités plus pratiques , puis la caisse HandySwift . Importez-le simplement dans votre projet et vous pouvez utiliser le code ci-dessus sans ajouter vous-même d'extensions au projet.
la source
Il n'y a plus besoin d'extension ou de fonction supplémentaire. Vous pouvez écrire comme ça:
la source
Vous pouvez utiliser,
la source
Vous pouvez utiliser la fonction bridgeToObjectiveC () pour faire du dictionnaire un NSDictionary.
Sera comme le suivant:
Ensuite, vous pouvez reconvertir le NSDictionary (combiner) ou faire quoi que ce soit.
la source
Le résultat est un NSMutableDictionary pas un dictionnaire typé Swift, mais la syntaxe pour l'utiliser est la même (
out["a"] == 1
dans ce cas) donc vous n'auriez un problème que si vous utilisez un code tiers qui attend un dictionnaire Swift, ou vraiment besoin de la vérification de type.La réponse courte ici est que vous devez en fait faire une boucle. Même si vous ne le saisissez pas explicitement, c'est ce que fera la méthode que vous appelez (addEntriesFromDictionary: here). Je suggérerais que si vous ne savez pas pourquoi cela serait le cas, vous devriez réfléchir à la façon dont vous fusionneriez les nœuds feuilles de deux arbres B.
Si vous avez vraiment besoin d'un type de dictionnaire natif Swift en retour, je vous suggère:
L'inconvénient de cette approche est que l'index du dictionnaire - quelle que soit la méthode utilisée - peut être reconstruit plusieurs fois dans la boucle, donc en pratique, c'est environ 10 fois plus lent que l'approche NSMutableDictionary.
la source
Toutes ces réponses sont compliquées. Voici ma solution pour swift 2.2:
la source
Mes besoins étaient différents, j'avais besoin de fusionner des ensembles de données imbriqués incomplets sans écraser.
C'était plus difficile que je ne le voulais. Le défi consistait à mapper du typage dynamique au typage statique, et j'ai utilisé des protocoles pour résoudre ce problème.
Il convient également de noter que lorsque vous utilisez la syntaxe littérale du dictionnaire, vous obtenez en fait les types de base, qui ne prennent pas les extensions de protocole. J'ai abandonné mes efforts pour les soutenir car je ne pouvais pas trouver un moyen facile de valider l'uniformité des éléments de la collection.
la source
Swift 2.2
la source
J'utiliserais simplement la bibliothèque Dollar .
https://github.com/ankurp/Dollar/#merge---merge-1
Fusionne tous les dictionnaires ensemble et le dernier dictionnaire remplace la valeur à une clé donnée
la source
Voici une belle extension que j'ai écrite ...
utiliser:
Ensuite, dict1 sera modifié en
la source