Dictionary
を使用して、あるDictionary
を別のSwift
に追加するにはどうすればよいですか?
AlamoFire
ライブラリを使用してJSON
をREST server
に送信しています。
辞書1
var dict1: [String: AnyObject] = [
kFacebook: [
kToken: token
]
]
辞書2
var dict2: [String: AnyObject] = [
kRequest: [
kTargetUserId: userId
]
]
以下に示すように2つの辞書を組み合わせて新しい辞書を作成するにはどうすればよいですか?
let parameters: [String: AnyObject] = [
kFacebook: [
kToken: token
],
kRequest: [
kTargetUserId: userId
]
]
dict1 += dict2
を試しましたが、コンパイルエラーが発生しました。
二項演算子「+ =」は、2つの「[String:AnyObject]」オペランドに適用できません
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)
素晴らしいDollar&Centプロジェクトを参照してください https://github.com/ankurp/Cent/blob/master/Sources/Dictionary.Swift
私はこのアプローチが大好きです:
dicFrom.forEach { (key, value) in dicTo[key] = value }
Swift 4および5
With Swift 4 Appleは、2つの辞書をマージするためのより良いアプローチを導入します。
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]
ここには2つのオプションがあります(コンテナで動作するほとんどの機能と同様):
merge
は既存の辞書を変更しますmerging
は新しい辞書を返しますSequenceType.forEach
(Dictionary
で実装)は、辞書の要素を別の辞書に追加するエレガントなソリューションを提供します。
dic1.forEach { dic2[$0] = $1 }
例えば
func testMergeDictionaries() {
let dic1 = [1:"foo"]
var dic2 = [2:"bar"]
dic1.forEach { dic2[$0] = $1 }
XCTAssertEqual(dic2[1], "foo")
}
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]
私のニーズは異なっていたので、合併するのではなく統合したかったのです。
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]]
私はもっと簡単な解決策を望んでいましたが、これが私がやったことです。課題は、動的な型付けから静的な型付けへの移行であり、これを解決するためにプロトコルを使用しました。
また、辞書リテラル構文を使用すると、実際に基本タイプが取得されることに注意してください。これは、プロトコル拡張を取得しません。コレクション要素の均一性を簡単に検証できないため、それらをサポートする努力を中止しました。
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)")
このアプローチを試してください
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)
以下を印刷します。
{
kFacebook = {
kToken = token;
};
kRequest = {
kTargetUserId = userId;
};
}
それが役に立てば幸い !!
以下のコードを使用して、Swiftで2つの辞書インスタンスを組み合わせることができます。
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
}
}