Arrays in Swift unterstützen den Operator + =, um den Inhalt eines Arrays einem anderen hinzuzufügen. Gibt es eine einfache Möglichkeit, dies für ein Wörterbuch zu tun?
z.B:
var dict1 = ["a" : "foo"]
var dict2 = ["b" : "bar"]
var combinedDict = ... (some way of combining dict1 & dict2 without looping)
dictionary
swift
rostig
quelle
quelle
fromDict.forEach {intoDict[$0] = $1}
Antworten:
Sie können einen
+=
Operator fürDictionary
z.quelle
@assignment
und fallen lassenreturn
, du mutierst schon links. Edit: eigentlich, obwohl ich keine Fehler bekomme, denke ich@assignment
sollte bleiben.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}) }
In Swift 4 sollte man verwenden
merging(_:uniquingKeysWith:)
:Beispiel:
quelle
[NSMutableDictionary addEntriesFromDictionary:]
.Wie wäre es mit
Dadurch werden alle Schlüssel und Werte von dict2 zu dict1 hinzugefügt.
quelle
Closure tuple parameter '(key: _, value: _)' does not support destructuring
(zumindest zum Zeitpunkt dieses Schreibens). Man müsste die Schließung gemäß [dieser Stackoverflow-Antwort] ( stackoverflow.com/questions/44945967/… ) umstrukturieren :Derzeit gibt es in der Swift Standard Library-Referenz für Wörterbuch keine Möglichkeit, ein Wörterbuch einfach mit einem anderen zu aktualisieren.
Sie können dazu eine Erweiterung schreiben
quelle
Swift 4 bietet
merging(_:uniquingKeysWith:)
also für Ihren Fall:Der Kurzschluss wird zurückgegeben
$1
, daher wird der Wert von dict2 verwendet, wenn ein Konflikt mit den Schlüsseln vorliegt.quelle
- (void)addEntriesFromDictionary:(NSDictionary<KeyType, ObjectType> *)otherDictionary;
. In Bezug auf die Vorgehensweise bei Duplikaten heißt es: "Wenn beide Wörterbücher denselben Schlüssel enthalten, wird dem vorherigen Wertobjekt des empfangenden Wörterbuchs für diesen Schlüssel eine Freigabemeldung gesendet, und das neue Wertobjekt nimmt seinen Platz ein." Die Swift-Version oder in Merge (_: uniquingKeysWith :), die den zweiten Wert zurückgibt$1
, ist dieselbe wie das, was sieaddEntriesFromDictionary
tut.Es ist nicht in die Swift-Bibliothek integriert, aber Sie können beim Überladen von Operatoren hinzufügen, was Sie möchten, z.
Dies überlastet die
+
Operator für Wörterbücher, mit denen Sie jetzt Wörterbücher mit dem+
Operator hinzufügen können, z.quelle
map
die erstefor (k, v)...
Schleife entfernen und löschen , wenn Sie denleft
Parameter als deklarierenvar
und dann einfach Werte daraus kopierenright
.+
Infix-Operator kein erwartetes Verhalten ist .+
Operatorüberladung auch keine Methode istDictionary
, sondern eine einfache Funktion. Die Änderungen, die Sie an einem variablenleft
Parameter vornehmen, sind außerhalb der Funktion nicht sichtbar.Swift 3:
quelle
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
quelle
union
Funktion wird der Wert a übergebenvar
, was bedeutet, dass das kopierte Wörterbuch mutiert werden kann. Es ist ein bisschen sauberer alsfunc union(dictionary: Dictionary) -> Dictionary { var dict2 = dictionary; dict2.unionInPlace(self); return dict2 }
, wenn auch nur um eine Zeile.var dictionary = dictionary
. Von hier: github.com/apple/swift-evolution/blob/master/proposals/…<Key, Value>
diese hinzuDictionary
.Unveränderlich
Ich bevorzuge es, unveränderliche Wörterbücher mit dem
+
Operator zu kombinieren / zu vereinen , also habe ich es wie folgt implementiert:Veränderlich
quelle
right.reduce(left)
, zumindest ist das das erwartete Verhalten imo (und es ist das Verhalten Ihres zweiten Beispiels) - dh.["A":1] + ["A":2]
sollte ausgeben["A":2]
Sie müssen jetzt keine Wörterbucherweiterungen mehr haben. Das Swift-Wörterbuch (Xcode 9.0+) verfügt über eine entsprechende Funktionalität. Schauen Sie hier . Unten finden Sie ein Beispiel für die Verwendung
quelle
oldDictionary.merge(newDictionary) { $1 }
Eine besser lesbare Variante mit einer Erweiterung.
quelle
Sie können dies versuchen
quelle
Sie können auch Reduzieren verwenden, um sie zusammenzuführen. Versuchen Sie dies auf dem Spielplatz
quelle
d
undp
?Ich empfehle die SwifterSwift Library . Wenn Sie jedoch nicht die gesamte Bibliothek und all ihre großartigen Ergänzungen verwenden möchten, können Sie einfach die Erweiterung des Wörterbuchs verwenden:
Swift 3+
quelle
Sie können die Schlüsselwertkombinationen für den Wert, den Sie zusammenführen möchten, durchlaufen und über die Methode updateValue (forKey :) hinzufügen:
Jetzt wurden alle Werte von dictionaryTwo zu dictionaryOne hinzugefügt.
quelle
Das gleiche wie die Antwort von @ farhadf, jedoch für Swift 3 übernommen:
quelle
Swift 3, Wörterbucherweiterung:
quelle
Einige noch optimierte Überladungen für Swift 4:
quelle
Sie können eine
Dictionary
Erweiterung wie folgt hinzufügen :Dann ist die Verwendung so einfach wie die folgende:
Wenn Sie es vorziehen , einen Rahmen, der auch einige umfasst mehr praktische Funktionen dann Kasse HandySwift . Importieren Sie es einfach in Ihr Projekt und Sie können den obigen Code verwenden, ohne dem Projekt selbst Erweiterungen hinzuzufügen .
quelle
Es ist keine Erweiterung oder zusätzliche Funktion mehr erforderlich. Sie können so schreiben:
quelle
Sie können verwenden,
quelle
Mit der Funktion bridgeToObjectiveC () können Sie das Wörterbuch zu einem NSDictionary machen.
Wird wie folgt sein:
Dann können Sie das NSDictionary (konvertieren) zurück konvertieren oder was auch immer tun.
quelle
Das Ergebnis ist ein NSMutableDictionary, kein Swift-typisiertes Wörterbuch, aber die Syntax für die Verwendung ist dieselbe (
out["a"] == 1
in diesem Fall), sodass Sie nur dann ein Problem haben, wenn Sie Code von Drittanbietern verwenden, der ein Swift-Wörterbuch erwartet, oder wirklich brauche die Typprüfung.Die kurze Antwort hier ist, dass Sie tatsächlich eine Schleife durchführen müssen. Auch wenn Sie es nicht explizit eingeben, funktioniert die von Ihnen aufgerufene Methode (addEntriesFromDictionary: hier) genau so. Ich würde vorschlagen, wenn Sie sich nicht sicher sind, warum dies der Fall ist, sollten Sie überlegen, wie Sie die Blattknoten zweier B-Bäume zusammenführen würden.
Wenn Sie im Gegenzug wirklich einen nativen Swift-Wörterbuchtyp benötigen, würde ich vorschlagen:
Der Nachteil dieses Ansatzes ist, dass der Wörterbuchindex - wie auch immer er ausgeführt wird - möglicherweise mehrmals in der Schleife neu erstellt wird. In der Praxis ist dies also etwa 10-mal langsamer als der Ansatz von NSMutableDictionary.
quelle
Alle diese Antworten sind kompliziert. Dies ist meine Lösung für Swift 2.2:
quelle
Meine Anforderungen waren unterschiedlich, ich musste unvollständige verschachtelte Datensätze zusammenführen, ohne zu überladen.
Das war schwieriger als ich es wollte. Die Herausforderung bestand in der Zuordnung von dynamischer Typisierung zu statischer Typisierung, und ich habe Protokolle verwendet, um dies zu lösen.
Bemerkenswert ist auch, dass Sie bei Verwendung der Wörterbuchliteral-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.
quelle
Swift 2.2
quelle
Ich würde nur die Dollar- Bibliothek benutzen .
https://github.com/ankurp/Dollar/#merge---merge-1
Fügt alle Wörterbücher zusammen und das letztere Wörterbuch überschreibt den Wert bei einem bestimmten Schlüssel
quelle
Hier ist eine schöne Erweiterung, die ich geschrieben habe ...
benutzen:
Dann wird dict1 in geändert
quelle