programing

항목 사전을 다른 사전에 추가하려면 어떻게 해야 합니까?

telecom 2023. 4. 15. 08:21
반응형

항목 사전을 다른 사전에 추가하려면 어떻게 해야 합니까?

Swift의 어레이는 += 연산자가 한 어레이의 내용을 다른 어레이에 추가할 수 있도록 지원합니다.사전을 위해 그것을 쉽게 할 수 있는 방법이 있나요?

예:

var dict1 = ["a" : "foo"]
var dict2 = ["b" : "bar"]

var combinedDict = ... (some way of combining dict1 & dict2 without looping)

할 수 .+=를 지정합니다.Dictionary ...timeout,

func += <K, V> (left: inout [K:V], right: [K:V]) { 
    for (k, v) in right { 
        left[k] = v
    } 
}

Swift 4에서는 다음을 사용합니다.

예:

let dictA = ["x" : 1, "y": 2, "z": 3]
let dictB = ["x" : 11, "y": 22, "w": 0]

let resultA = dictA.merging(dictB, uniquingKeysWith: { (first, _) in first })
let resultB = dictA.merging(dictB, uniquingKeysWith: { (_, last) in last })

print(resultA) // ["x": 1, "y": 2, "z": 3, "w": 0]
print(resultB) // ["x": 11, "y": 22, "z": 3, "w": 0]

Swift 4는 다음을 제공합니다.

let combinedDict = dict1.merging(dict2) { $1 }

은 을 반환한다.$1dict2로 하겠습니다.

어때.

dict2.forEach { (k,v) in dict1[k] = v }

그러면 dict2의 모든 키와 값이 dict1에 추가됩니다.

현재 Swift Standard Library Reference for Dictionary를 살펴보면 다른 사전을 쉽게 업데이트할 수 있는 방법이 없습니다.

확장자를 써서 할 수 있습니다.

var dict1 = ["a" : "foo"]
var dict2 = ["b" : "bar"]

extension Dictionary {
    mutating func update(other:Dictionary) {
        for (key,value) in other {
            self.updateValue(value, forKey:key)
        }
    }
}

dict1.update(dict2)
// dict1 is now ["a" : "foo", "b" : "bar]

Swift 라이브러리에 내장되어 있지는 않지만 연산자 오버로드로 원하는 것을 추가할 수 있습니다. 예:

func + <K,V>(left: Dictionary<K,V>, right: Dictionary<K,V>) 
    -> Dictionary<K,V> 
{
    var map = Dictionary<K,V>()
    for (k, v) in left {
        map[k] = v
    }
    for (k, v) in right {
        map[k] = v
    }
    return map
}

하면 .+로, 이 연산자를 할 수 .+ operator). §:

var dict1 = ["a" : "foo"]
var dict2 = ["b" : "bar"]

var dict3 = dict1 + dict2 // ["a": "foo", "b": "bar"]

스위프트 3:

extension Dictionary {

    mutating func merge(with dictionary: Dictionary) {
        dictionary.forEach { updateValue($1, forKey: $0) }
    }

    func merged(with dictionary: Dictionary) -> Dictionary {
        var dict = self
        dict.merge(with: dictionary)
        return dict
    }
}

let a = ["a":"b"]
let b = ["1":"2"]
let c = a.merged(with: b)

print(c) //["a": "b", "1": "2"]

Swift 2.0

extension Dictionary {

    mutating func unionInPlace(dictionary: Dictionary) {
        dictionary.forEach { self.updateValue($1, forKey: $0) }
    }

    func union(var dictionary: Dictionary) -> Dictionary {
        dictionary.unionInPlace(self)
        return dictionary
    }
}

지금은 사전 확장자를 사용할 필요가 없습니다.Swift(Xcode 9.0+) 사전에는 이를 위한 기능이 있습니다.여기 좀 보세요.다음은 사용 방법에 대한 예입니다.

  var oldDictionary = ["a": 1, "b": 2]
  var newDictionary = ["a": 10000, "b": 10000, "c": 4]

  oldDictionary.merge(newDictionary) { (oldValue, newValue) -> Int in
        // This closure return what value to consider if repeated keys are found
        return newValue 
  }
  print(oldDictionary) // Prints ["b": 10000, "a": 10000, "c": 4]

불변의

과 불변의 한다.+오퍼레이터를 위해 다음과 같이 구현했습니다.

// Swift 2
func + <K,V> (left: Dictionary<K,V>, right: Dictionary<K,V>?) -> Dictionary<K,V> {
    guard let right = right else { return left }
    return left.reduce(right) {
        var new = $0 as [K:V]
        new.updateValue($1.1, forKey: $1.0)
        return new
    }
}

let moreAttributes: [String:AnyObject] = ["Function":"authenticate"]
let attributes: [String:AnyObject] = ["File":"Auth.swift"]

attributes + moreAttributes + nil //["Function": "authenticate", "File": "Auth.swift"]    
attributes + moreAttributes //["Function": "authenticate", "File": "Auth.swift"]
attributes + nil //["File": "Auth.swift"]

변이 가능

// Swift 2
func += <K,V> (inout left: Dictionary<K,V>, right: Dictionary<K,V>?) {
    guard let right = right else { return }
    right.forEach { key, value in
        left.updateValue(value, forKey: key)
    }
}

let moreAttributes: [String:AnyObject] = ["Function":"authenticate"]
var attributes: [String:AnyObject] = ["File":"Auth.swift"]

attributes += nil //["File": "Auth.swift"]
attributes += moreAttributes //["File": "Auth.swift", "Function": "authenticate"]

확장자를 사용한 보다 읽기 쉬운 변형.

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

이거 드셔보세요

var dict1 = ["a" : "foo"]
var dict2 = ["b" : "bar"]

var temp = NSMutableDictionary(dictionary: dict1);
temp.addEntriesFromDictionary(dict2)

reduce를 사용하여 이들을 병합할 수도 있습니다.놀이터에서 먹어보세요.

let d1 = ["a":"foo","b":"bar"]
let d2 = ["c":"car","d":"door"]

let d3 = d1.reduce(d2) { (var d, p) in
   d[p.0] = p.1
   return d
}

Swift 4의 경우 보다 효율적인 과부하가 발생합니다.

extension Dictionary {
    static func += (lhs: inout [Key:Value], rhs: [Key:Value]) {
        lhs.merge(rhs){$1}
    }
    static func + (lhs: [Key:Value], rhs: [Key:Value]) -> [Key:Value] {
        return lhs.merging(rhs){$1}
    }
}

스위프터 스위프트 도서관을 추천합니다.그러나 라이브러리 전체와 라이브러리 추가 기능을 사용하지 않으려면 사전의 확장 기능을 사용할 수 있습니다.

스위프트 3 이상

public extension Dictionary {
    public static func +=(lhs: inout [Key: Value], rhs: [Key: Value]) {
        rhs.forEach({ lhs[$0] = $1})
    }
}

더 이상 확장이나 추가 기능이 필요하지 않습니다.다음과 같이 쓸 수 있습니다.

firstDictionary.merge(secondDictionary) { (value1, value2) -> AnyObject in
        return object2 // what you want to return if keys same.
    }

결합할 값의 키 값 조합을 반복하여 updateValue(forKey:) 방식으로 추가할 수 있습니다.

dictionaryTwo.forEach {
    dictionaryOne.updateValue($1, forKey: $0)
}

이것으로 dictionary2의 모든 값이 dictionary1에 추가되었습니다.

@farhadf의 답변과 동일하지만 Swift 3에서 채택되었습니다.

let sourceDict1 = [1: "one", 2: "two"]
let sourceDict2 = [3: "three", 4: "four"]

let result = sourceDict1.reduce(sourceDict2) { (partialResult , pair) in
    var partialResult = partialResult //without this line we could not modify the dictionary
    partialResult[pair.0] = pair.1
    return partialResult
}

Swift 3, 사전 확장자:

public extension Dictionary {

    public static func +=(lhs: inout Dictionary, rhs: Dictionary) {
        for (k, v) in rhs {
            lhs[k] = v
        }
    }

}

사용할 수 있습니다.

func addAll(from: [String: Any], into: [String: Any]){
    from.forEach {into[$0] = $1}
}

다음과 같이 확장을 추가할 수 있습니다.

extension Dictionary {
    func mergedWith(otherDictionary: [Key: Value]) -> [Key: Value] {
        var mergedDict: [Key: Value] = [:]
        [self, otherDictionary].forEach { dict in
            for (key, value) in dict {
                mergedDict[key] = value
            }
        }
        return mergedDict
    }
}

사용법은 다음과 같이 간단합니다.

var dict1 = ["a" : "foo"]
var dict2 = ["b" : "bar"]

var combinedDict = dict1.mergedWith(dict2)
// => ["a": "foo", "b": "bar"]

보다 편리한 기능을 갖춘 프레임워크를 원하신다면 HandySwift를 확인해 보십시오.프로젝트를 Import하기만 하면 프로젝트에 직접 확장자를 추가하지 않고도 위의 코드를 사용할 수 있습니다.

bridgeToObjectiveC() 함수를 사용하여 사전을 NSDictionary로 만들 수 있습니다.

다음과 같습니다.

var dict1 = ["a":"Foo"]
var dict2 = ["b":"Boo"]

var combinedDict = dict1.bridgeToObjectiveC()
var mutiDict1 : NSMutableDictionary! = combinedDict.mutableCopy() as NSMutableDictionary

var combineDict2 = dict2.bridgeToObjectiveC()

var combine = mutiDict1.addEntriesFromDictionary(combineDict2)

그런 다음 NSDictionary(결합)를 다시 변환하거나 다른 작업을 수행할 수 있습니다.

import Foundation

let x = ["a":1]
let y = ["b":2]

let out = NSMutableDictionary(dictionary: x)
out.addEntriesFromDictionary(y)

만, (「NSMutableDictionary」Swift).out["a"] == 1따라서 Swift 사전을 필요로 하는 서드파티 코드를 사용하거나 정말로 유형 확인이 필요한 경우에만 문제가 발생할 수 있습니다.

여기서 간단한 답은 실제로 루프해야 한다는 것입니다.명시적으로 입력하지 않아도 호출하는 메서드(addEntriesFromDictionary:여기서)가 그렇게 됩니다.그 이유가 불분명한 경우에는 두 B-Tree의 리프 노드를 어떻게 결합할지를 검토해야 합니다.

정말로 Swift 네이티브 딕셔너리가 필요한 경우, 다음과 같이 제안합니다.

let x = ["a":1]
let y = ["b":2]

var out = x
for (k, v) in y {
    out[k] = v
}

이 접근법의 단점은 사전 인덱스가 루프 내에서 여러 번 재구축될 수 있다는 것입니다. 따라서 실제로는 NSMutableDictionary 접근법보다 약 10배 느립니다.

이러한 응답은 모두 복잡합니다.이것은 swift 2.2를 위한 솔루션입니다.

    //get first dictionnary
    let finalDictionnary : NSMutableDictionary = self.getBasicDict()
    //cast second dictionnary as [NSObject : AnyObject]
    let secondDictionnary : [NSObject : AnyObject] = self.getOtherDict() as [NSObject : AnyObject]
    //merge dictionnary into the first one
    finalDictionnary.addEntriesFromDictionary(secondDictionnary) 

요구 사항이 달랐습니다. 클로버링 없이 불완전한 중첩 데이터 세트를 병합해야 했습니다.

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)")

스위프트 2.2

func + <K,V>(left: [K : V], right: [K : V]) -> [K : V] {
    var result = [K:V]()

    for (key,value) in left {
        result[key] = value
    }

    for (key,value) in right {
        result[key] = value
    }
    return result
}

난 그냥 달러 도서관을 이용하겠어.

https://github.com/ankurp/Dollar/ #syslog---syslog-1

모든 사전을 병합하고 후자의 사전은 지정된 키의 값을 재정의합니다.

let dict: Dictionary<String, Int> = ["Dog": 1, "Cat": 2]
let dict2: Dictionary<String, Int> = ["Cow": 3]
let dict3: Dictionary<String, Int> = ["Sheep": 4]
$.merge(dict, dict2, dict3)
=> ["Dog": 1, "Cat": 2, "Cow": 3, "Sheep": 4]

여기 내가 쓴 멋진 확장자가 있다...

extension Dictionary where Value: Any {
    public func mergeOnto(target: [Key: Value]?) -> [Key: Value] {
        guard let target = target else { return self }
        return self.merging(target) { current, _ in current }
    }
}

사용 방법:

var dict1 = ["cat": 5, "dog": 6]
var dict2 = ["dog": 9, "rodent": 10]

dict1 = dict1.mergeOnto(target: dict2)

그런 다음 dict1은 다음과 같이 수정됩니다.

["cat": 5, "dog": 6, "rodent": 10]

언급URL : https://stackoverflow.com/questions/24051904/how-do-you-add-a-dictionary-of-items-into-another-dictionary

반응형