sourcecode

Swift에서 두 개의 사전 인스턴스를 결합하려면 어떻게 해야 합니까?

codebag 2023. 4. 3. 21:28
반응형

Swift에서 두 개의 사전 인스턴스를 결합하려면 어떻게 해야 합니까?

어떻게 추가합니까?Dictionary타인에게DictionarySwift를 사용할 수 있습니까?

사용하고 있는 것은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

반응형