Swift에서 두 개의 사전 인스턴스를 결합하려면 어떻게 해야 합니까?
어떻게 추가합니까?Dictionary
타인에게Dictionary
Swift를 사용할 수 있습니까?
사용하고 있는 것은AlamoFire
라이브러리를 사용하여 JSON 콘텐츠를 REST 서버로 전송합니다.
딕셔너리 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]' 피연산자 두 개에 적용할 수 없습니다.
이 접근법이 마음에 듭니다.
dicFrom.forEach { (key, value) in dicTo[key] = value }
스위프트 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
새 사전을 반환합니다.
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)
멋진 달러&센트 프로젝트 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 }
Swift 4에는 다음과 같은 새로운 기능이 있습니다.let parameters = dict1.reduce(into: dict2) { (r, e) in r[e.0] = e.1 }
표준 라이브러리를 자세히 살펴보는 것이 매우 중요합니다.map
,reduce
,dropFirst
,forEach
등은 간결한 코드의 핵심입니다.기능하는 비트는 재미있다!
extension Dictionary {
static func +=(lhs: inout Self, rhs: Self) {
lhs.merge(rhs) { _ , new in new }
}
static func +=<S: Sequence>(lhs: inout Self, rhs: S) where S.Element == (Key, Value) {
lhs.merge(rhs) { _ , new in new }
}
}
var dic = ["test1": 1]
dic += ["test2": 2]
dic // ["test1": 1, "test2": 2]
dic += [("test2", 3),("test3", 4)]
dic // ["test3": 4, "test1": 1, "test2": 3]
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")
}
내 요구는 달랐고, 난 합병하고 싶었지, 클로버가 아니었다.
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에서 두 개의 사전 인스턴스를 결합할 수 있습니다.
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
}
}
사전을 선언하기 위해 let 키워드를 사용하고 있으므로 사전을 상수로 선언하는 데 사용되므로 변경할 수 없습니다.
var 키워드로 변경하면 효과가 있습니다.
var dict1: [String: AnyObject] = [
kFacebook: [
kToken: token
]
]
var dict2: [String: AnyObject] = [
kRequest: [
kTargetUserId: userId
]
]
dict1 += dict2
언급URL : https://stackoverflow.com/questions/26728477/how-can-i-combine-two-dictionary-instances-in-swift
'sourcecode' 카테고리의 다른 글
정수가 선행 0으로 시작하는 경우 JSON이 유효하지 않은 이유는 무엇입니까? (0) | 2023.04.03 |
---|---|
이 "주의: 요청이 아직 크롬으로 완료되지 않았습니다"를 해결하는 방법 (0) | 2023.04.03 |
react.js & redux에서 componentDisMount가 여러 번 호출된 이유는 무엇입니까? (0) | 2023.04.03 |
주석 지정 콩 이름이 호환되지 않는 기존 콩 이름과 충돌합니다. (0) | 2023.03.29 |
요소에 속성을 추가하는 각도 지시문? (0) | 2023.03.29 |