을 사용하여 Dictionary
서로 Dictionary
를 Swift
어떻게 추가 합니까?
내가 사용하고 AlamoFire
을 보내 라이브러리를 JSON
A를 REST server
.
사전 1
var dict1: [String: AnyObject] = [
kFacebook: [
kToken: token
]
]
사전 2
var dict2: [String: AnyObject] = [
kRequest: [
kTargetUserId: userId
]
]
두 사전을 결합하여 아래와 같이 새 사전을 만들려면 어떻게해야합니까?
let parameters: [String: AnyObject] = [
kFacebook: [
kToken: token
],
kRequest: [
kTargetUserId: userId
]
]
시도 dict1 += dict2
했지만 컴파일 오류가 발생했습니다.
이항 연산자 ‘+ =’는 두 개의 ‘[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
Swift 4를 통해 Apple은 두 개의 사전을 병합하는 더 나은 접근 방식을 도입했습니다.
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
새 사전을 반환합니다.
답변
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 }
Swift 4에는 새로운 기능이 있습니다.
let parameters = dict1.reduce(into: dict2) { (r, e) in r[e.0] = e.1 }
그것은 표준 라이브러리 주위를 파고 정말 중요 : map
, reduce
, dropFirst
, forEach
등 간결한 코드의 스테이플입니다. 기능적인 부분은 재미 있습니다!
답변
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]
답변
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")
}
답변
merge 키워드를 사용하여 더 나은 방법으로 사전을 병합 할 수 있습니다.
var dictionary = ["a": 1, "b": 2]
/// Keeping existing value for key "a":
dictionary.merge(["a": 3, "c": 4]) { (current, _) in current }
// ["b": 2, "a": 1, "c": 4]
답변
내 요구 사항은 달랐고, 합병을 원했고 엉망진창이 아니 었습니다.
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)")