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 }
挖掘标准库非常重要: map
, reduce
, dropFirst
, forEach
等都是简洁代码的主要部分。 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; }]]