Swift:如何组合两个Dictionary实例?

如何使用Swift[Dictionary]附加到另一个[Dictionary]

我正在使用AlamoFire库将JSON发送到REST server

词典1

 let dict1: [String: AnyObject] = [ kFacebook: [ kToken: token ] ] 

词典2

 let dict2: [String: AnyObject] = [ kRequest: [ kTargetUserId: userId ] ] 

如何将两个字典组合成一个新字典,如下所示?

 let parameters: [String: AnyObject] = [ kFacebook: [ kToken: token ], kRequest: [ kTargetUserId: userId ] ] 

我试过dict1 += dict2但有一个编译错误。

提前致谢!

 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

对于Swift> = 2.2:
let parameters = dict1.reduce(dict2) { r, e in var r = r; r[e.0] = e.1; return r }

对于Swift <2.2:
let parameters = dict1.reduce(dict2) { (var r, e) in r[e.0] = e.1; return r }

挖掘标准库非常重要: mapreducedropFirstforEach等都是简洁代码的主要部分。 function位很有趣!

我喜欢这种方法:

dicFrom.forEach { (key, value) in dicTo[key] = value }

斯威夫特4

随着Swift 4苹果推出了一个更好的方法来合并两本字典:

 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] 

这里有两个选项(就像大多数在容器上运行的函数一样):

  • merge变异现有的字典
  • merging创build一个新的字典

SequenceType.forEach (由Dictionary实现)提供了一个优雅的解决scheme,可以将字典的元素添加到另一个字典中。

 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] 

尝试这种方法

  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; }; 

}

希望能帮助到你 !!

我的需求是不同的,我想合并而不是打破。

 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]] 

我希望有一个更简单的解决scheme,但这是我最终的结果。 面临的挑战是从dynamicinput到静态input,我使用协议来解决这个问题。

另外值得注意的是,当你使用字典字面语法时,你实际上得到了基础types,它们没有select协议扩展。 我放弃了我的努力来支持这些,因为我找不到一个容易validation收集元素的统一性的方法。

 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关键字来声明字典,因此您无法对字典进行更改,因为它用于声明常量。

将其更改为var关键字,那么它会为你工作。

 var dict1: [String: AnyObject] = [ kFacebook: [ kToken: token ] ] var dict2: [String: AnyObject] = [ kRequest: [ kTargetUserId: userId ] ] dict1 += dict2 
 let dict1: [String: AnyObject] = [ "kFacebook": [ "kToken": "token" ] ] let dict2: [String: AnyObject] = [ "kRequest": [ "kTargetUserId": "userId" ] ] var ArrayOfDictionary = [dict1,dict2] println(ArrayOfDictionary) 

这印

 [[kFacebook: { kToken = token; }], [kRequest: { kTargetUserId = userId; }]]