आप किसी अन्य शब्दकोश में आइटम का एक शब्दकोश कैसे जोड़ते हैं


172

स्विफ्ट में एरे एक के एरे की सामग्री को दूसरे में जोड़ने के लिए + = ऑपरेटर का समर्थन करता है। वहाँ एक शब्दकोश के लिए यह करने के लिए एक आसान तरीका है?

उदाहरण के लिए:

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

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


fromDict.forEach {intoDict[$0] = $1}
सज्जाद हिसैन खान

जवाबों:


171

आप इसके +=लिए ऑपरेटर को परिभाषित कर सकते हैं Dictionary, जैसे,

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

1
अरे यार, मैंने इसके लिए उचित सामान्य घोषणा खोजने के लिए बहुत संघर्ष किया, मैंने इसके अलावा सब कुछ करने की कोशिश की। लेकिन आप छोड़ सकते हैं @assignmentऔर return, आप पहले से ही बाएं म्यूट कर रहे हैं। संपादित करें: वास्तव में, भले ही मुझे कोई त्रुटि न मिले, मुझे लगता है कि @assignmentरहना चाहिए।
रोलैंड

14
अधिक सिंटैक्स चीनी: func +=<K, V> (inout left: [K : V], right: [K : V]) { for (k, v) in right { left[k] = v } }
इवान वाविलोव

48
@animal_chin क्योंकि हमें स्वयं भाषा का आधा भाग लागू करना है? हाँ। प्रभावित किया। मुझे गलत मत समझो मैं ऑपरेटर को ओवरलोडिंग से प्यार करता हूं। मुझे बस बुनियादी सुविधाओं के लिए इसका उपयोग करने से प्यार नहीं है जो कि इसमें निर्मित होनी चाहिए।
devios1

2
@devios Haha तब इसे स्विफ्ट रेपो के लिए एक पुल अनुरोध करते हैं: D चूंकि जाहिर तौर पर Apple को नहीं
उतारा

6
स्विफ्टस्विफ्ट लाइब्रेरी से सीधे पुलिंग :public static func +=(lhs: inout [Key: Value], rhs: [Key: Value]) { rhs.forEach({ lhs[$0] = $1}) }
जस्टिन

99

स्विफ्ट 4 में, एक का उपयोग करना चाहिए merging(_:uniquingKeysWith:):

उदाहरण:

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]

1
// mutable: var dictA = ["x": 1, "y": 2, "z": 3] var dictB = ["x": 11, "y": 22, "w": 0] तानाशाही। मर्ज (डिक्टर्ब, uniquingKeysWith: {(पहले, _) पहले} में) प्रिंट (तानाशाही) // ["x": 1, "y": 2, "z": 3, "w": 0]
मुथुकुमार

1
इस उत्तर में दिखाया गया दूसरा उदाहरण इसके समकक्ष है [NSMutableDictionary addEntriesFromDictionary:]
orj

92

कैसा रहेगा

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

जो dict2 की सभी कुंजियों और मानों को dict1 में जोड़ता है।


43
अच्छा समाधान है। थोड़ा छोटा: dict2.forEach {dict1 [$ 0] = $ 1}
ब्रेट

1
यह एक महान समाधान है, लेकिन स्विफ्ट 4 के लिए, आपको सबसे अधिक संभावना एक त्रुटि बताते हुए मिलेगी Closure tuple parameter '(key: _, value: _)' does not support destructuring(कम से कम इस लेखन के समय)। एक [इस stackoverflow जवाब] (के अनुसार बंद के पुनर्गठन की आवश्यकता होगी stackoverflow.com/questions/44945967/... :)
JonnyB

78

वर्तमान में, शब्दकोश के लिए स्विफ्ट मानक पुस्तकालय संदर्भ को देखते हुए, एक दूसरे के साथ एक शब्दकोश को आसानी से अपडेट करने का कोई तरीका नहीं है।

आप इसे करने के लिए एक एक्सटेंशन लिख सकते हैं

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]

3
यह शब्दकोश के लिए विस्तार का एक बड़ा उपयोग है!
मार्क अटिनासी

76

स्विफ्ट 4 प्रदान करता है merging(_:uniquingKeysWith:), इसलिए आपके मामले के लिए:

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

शॉर्टहैंड क्लोजर रिटर्न $1, इसलिए कुंजियों के साथ संघर्ष होने पर ताना 2 के मूल्य का उपयोग किया जाएगा।


1
बस यह इंगित करना चाहता था कि यह सबसे संक्षिप्त और निकटतम है जो मैंने पाया है कि एप्पल प्रलेखन के लिए क्या कहता है - (void)addEntriesFromDictionary:(NSDictionary<KeyType, ObjectType> *)otherDictionary;। डुप्लिकेट के साथ क्या करना है, इस संबंध में, यह कहा गया है कि: "यदि दोनों शब्दकोशों में एक ही कुंजी है, तो उस कुंजी के लिए प्राप्त होने वाले शब्दकोश के पिछले मूल्य ऑब्जेक्ट को एक संदेश भेजा जाता है, और नया मान ऑब्जेक्ट इसकी जगह लेता है।", इसलिए स्विफ्ट संस्करण, या मर्ज में (_: uniquingKeysWith :), दूसरा मान लौटाता है $1, जो जैसा करता है वैसा ही addEntriesFromDictionaryहोता है।
टिम फूक्वा

31

यह स्विफ्ट लाइब्रेरी में नहीं बनाया गया है, लेकिन आप ऑपरेटर ओवरलोडिंग के साथ जो चाहें जोड़ सकते हैं, जैसे:

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
}

यह +शब्दकोशों के लिए +ऑपरेटर को अधिभारित करता है जिसे अब आप ऑपरेटर के साथ शब्दकोशों को जोड़ने के लिए उपयोग कर सकते हैं , उदाहरण के लिए:

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

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

1
आप इसे एक प्रश्न के अनुसार (= op प्रश्न के अनुसार) अद्यतन करने के लिए भी कर सकते हैं।
रॉड

3
आप mapपहले for (k, v)...लूप को छोड़ सकते हैं और छोड़ सकते हैं यदि आप leftपैरामीटर को घोषित करते हैं varऔर फिर rightउसमें से मानों को कॉपी करते हैं।
नैट कुक

2
@NateCook, उस शब्दकोश को म्यूट कर देगा जिसमें +infix ऑपरेटर के लिए अपेक्षित व्यवहार नहीं है ।
मिथक

उसके लिए धन्यवाद। आपका उत्तर संभवतः मेरे द्वारा पोस्ट किए गए नमूना कोड के लिए अधिक सटीक था, जबकि दूसरा वह था जो मैं अपने प्रश्न के आधार पर चाहता था। मेरा बुरा, वैसे भी आप दोनों को एक
उत्थान

2
@mythz यह वास्तव में उत्परिवर्तन नहीं है, क्योंकि +ऑपरेटर अधिभार या तो एक विधि नहीं है Dictionary, यह एक सरल कार्य है। एक परिवर्तनशील leftपैरामीटर में आपके द्वारा किए गए परिवर्तन फ़ंक्शन के बाहर दिखाई नहीं देंगे।
नैट कुक

28

स्विफ्ट 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"]

6
थोड़ा बेहतरfunc merged(with dictionary: Dictionary<Key,Value>) -> Dictionary<Key,Value> { var copy = self dictionary.forEach { copy.updateValue($1, forKey: $0) } return copy }
अलेक्जेंडर वासिनिन

16

स्विफ्ट 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
    }
}

एक गैर-उत्परिवर्तन समारोह से उस तरह उत्परिवर्तन समारोह को नहीं बुला सकते हैं
njzk2

unionसमारोह मूल्य में यह एक होना पारित कर दिया है var, कॉपी किया शब्दकोश अर्थ उत्परिवर्तित जा सकता है। यह func union(dictionary: Dictionary) -> Dictionary { var dict2 = dictionary; dict2.unionInPlace(self); return dict2 }केवल एक लाइन से , अगर थोड़ा क्लीनर है ।
MaddTheSane

2
var params हटाए गए हैं और स्विफ्ट 3 में हटा दिए जाएंगे। ऐसा करने का पसंदीदा तरीका अब शरीर में एक var घोषित करना है var dictionary = dictionary:। यहाँ से: github.com/apple/swift-evolution/blob/master/proposals/…
डैनियल वुड

चीजों को अधिक सुरक्षित बनाने के लिए, <Key, Value>उन Dictionaryएस में जोड़ें ।
राफेल

12

अडिग

मैं +ऑपरेटर के साथ अपरिवर्तनीय शब्दकोशों को जोड़ना / एकजुट करना पसंद करता हूं इसलिए मैंने इसे लागू किया:

// 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"]

5
मुझे समझ नहीं आता कि यह डिफ़ॉल्ट रूप से स्विफ्ट में क्यों नहीं बनाया गया है?
ioquatix

1
क्या आप अपने "अपरिवर्तनीय" समाधान में दाईं ओर ओवरराइड करने के लिए बाईं ओर से मूल्यों का इरादा रखते हैं? मुझे लगता है कि आपके पास इसका मतलब है right.reduce(left), कम से कम यह अपेक्षित व्यवहार imo है (और यह आपके दूसरे उदाहरण का व्यवहार है) - यानी। ["A":1] + ["A":2]उत्पादन करना चाहिए["A":2]
ccwasden

आउटपुट कोड से मेल खाता है। मैं चाहता हूं कि प्रारंभिक मूल्य सही पक्ष हो, जैसे अभी है।
रिकार्डोपेरेरा

12

अब कोई भी शब्दकोश एक्सटेंशन रखने की आवश्यकता नहीं है। स्विफ्ट (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]

2
मैं ऊपर के उदाहरण के लिए एक कार्यात्मक शैली जोड़ रहा:oldDictionary.merge(newDictionary) { $1 }
Andrej

11

एक एक्सटेंशन का उपयोग करके अधिक पठनीय संस्करण।

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

3
बहुत अच्छा और साफ समाधान!
user3441734

11

आप यह कोशिश कर सकते हैं

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

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

10

आप उन्हें मर्ज करने के लिए कम का उपयोग भी कर सकते हैं। खेल के मैदान में यह कोशिश करो

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
}

यह दिलचस्प लग रहा है, लेकिन क्या हैं dऔर p?
लूटना

1
डी कम ब्लॉक के प्रत्येक पुनरावृत्ति का स्थायी परिणाम है और पी संग्रह का तत्व है जिसे कम किया जा रहा है।
17

1
इस तेजी में दुर्घटना करने लगता है 3.0 बीटा
possen

var मापदंडों को स्विफ्ट 3 में दर्शाया गया है
दिमित्री क्लोचकोव

यह यहाँ वर्णित लोगों में से मेरा पसंदीदा समाधान है। महान संक्षिप्त समाधानों के लिए फिर से फिल्टर / मैप / जीत कम करें।
गोकिजी

7

मैं स्विफ्टस्विफ्ट लाइब्रेरी की सलाह देता हूं । हालाँकि, यदि आप संपूर्ण पुस्तकालय और उसके सभी महान परिवर्धन का उपयोग नहीं करना चाहते हैं, तो आप उनके शब्दकोश के विस्तार का उपयोग कर सकते हैं:

स्विफ्ट 3+

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

दरअसल, SE-110 को वापस कर दिया गया है, इसलिए स्विफ्ट 4 संस्करण स्विफ्ट 3 संस्करण के समान होना चाहिए।
बॉलपॉइंटबैन

5

आप मुख्य मूल्य संयोजनों पर पुनरावृत्ति कर सकते हैं, जिस मूल्य को आप मर्ज करना चाहते हैं और उन्हें अद्यतन के माध्यम से जोड़ना चाहते हैं (forKo :):

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

अब शब्दकोश के सभी मूल्यों को शब्दकोश में जोड़ा गया।


4

@ फरहाद के जवाब के समान लेकिन स्विफ्ट 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
}

4

स्विफ्ट 3, शब्दकोश एक्सटेंशन:

public extension Dictionary {

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

}

4

स्विफ्ट 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

आप इस तरह से एक Dictionaryएक्सटेंशन जोड़ सकते हैं :

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 चेकआउट करें । बस इसे अपनी परियोजना में आयात करें और आप स्वयं परियोजना में कोई भी एक्सटेंशन जोड़े बिना उपरोक्त कोड का उपयोग कर सकते हैं ।


किसी एकल फ़ंक्शन का उपयोग करने के लिए लाइब्रेरी स्थापित करना खराब अभ्यास है
हैकॉज़

@HackaZach: मैंने सिर्फ अपने जवाब को अपडेट किया है ताकि पूरे पुस्तकालय को शामिल करने से रोकने के लिए फ्रेमवर्क के उचित हिस्से को शामिल किया जा सके यदि केवल इस छोटे हिस्से की आवश्यकता है। मैं उन लोगों के लिए फ्रेमवर्क के लिए संकेत रख रहा हूं जो इसकी कई विशेषताओं का उपयोग करना चाहते हैं। मुझे आशा है कि यह अच्छा अभ्यास रखने में मदद करता है!
जीहुत

3

अब और कोई अतिरिक्त विस्तार या किसी अतिरिक्त दुर्गंध की आवश्यकता नहीं है। आप इस तरह लिख सकते हैं:

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


1

डिक्शनरी को एनएसएडर बनाने के लिए आप ब्रिजटाउबजेक्टिव () फ़ंक्शन का उपयोग कर सकते हैं।

निम्नलिखित की तरह होगा:

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)

फिर आप एनएसबर्ड (कंबाइन) को वापस कन्वर्ट कर सकते हैं या जो भी कर सकते हैं।


क्षमा करें, आपका वास्तव में क्या मतलब है?
एंटोन

सिर्फ एक प्राथमिकता। भाषाओं के बीच पुल बनाने के लिए लगता है। एक ही भाषा के दायरे में रहने के लिए बेहतर है, जबकि एक साथ obj-c तेजी से मर जाते हैं।
TruMan1

2
हाँ, मैं इस उत्तर का शाब्दिक दिन स्विफ्ट की घोषणा पर एक कारण तैनात ....... तो वहाँ था
एंटोन

1
import Foundation

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

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

परिणाम एक NSMutableDictionary एक स्विफ्ट टाइप शब्दकोश नहीं है, लेकिन यह उपयोग करने के लिए वाक्यविन्यास एक ही है (out["a"] == 1 इस मामले में) तो आप केवल एक समस्या है अगर आप तीसरे पक्ष के कोड का उपयोग कर रहे हैं जो एक स्विफ्ट शब्दकोश की अपेक्षा करता है, या वास्तव में जाँच की आवश्यकता है।

यहां संक्षिप्त उत्तर यह है कि आपको वास्तव में लूप करना है। यहां तक ​​कि अगर आप इसे स्पष्ट रूप से दर्ज नहीं कर रहे हैं, तो यही वह विधि है जिसे आप कॉल कर रहे हैं (addEntriesFromDictionary: यहाँ)। मेरा सुझाव है कि यदि आप इस बात पर थोड़ा अस्पष्ट हैं कि ऐसा क्यों होगा तो आपको इस बात पर विचार करना चाहिए कि आप दो बी-पेड़ों के पत्तों के नोड्स का विलय कैसे करेंगे।

यदि आपको वास्तव में बदले में एक स्विफ्ट देशी शब्दकोश प्रकार की आवश्यकता है, तो मेरा सुझाव है:

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

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

इस दृष्टिकोण का नकारात्मक पहलू यह है कि डिक्शनरी इंडेक्स - हालाँकि ऐसा हो चुका है - कई बार लूप में फिर से बनाया जा सकता है, इसलिए व्यवहार में यह NSMutableDictionary दृष्टिकोण की तुलना में लगभग 10x धीमा है।


1

ये सभी प्रतिक्रियाएँ जटिल हैं। यह तेजी से 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) 

यह केवल NSMutableDictionary और देशी स्विफ्ट शब्दकोशों पर काम करता है, दुर्भाग्य से। काश, यह स्विफ्ट को मूल रूप से जोड़ा जाता।
बजे क्रिस पावेलियो

0

मेरी ज़रूरतें अलग थीं, मुझे क्लोबबेरिंग के बिना अधूरे नेस्टेड डेटा सेट को मर्ज करने की ज़रूरत थी।

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

0

स्विफ्ट 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
}

यदि आप इसे लगाते हैं तो आप पहला लूप निकाल सकते हैं: `var result = left`
NikeAlive

0

मैं सिर्फ डॉलर लाइब्रेरी का उपयोग करूंगा ।

https://github.com/ankurp/Dollar/#merge---merge-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]

5
jQuery वापस याय है!
बेन सिनक्लेयर

0

यहाँ एक अच्छा विस्तार मैंने लिखा है ...

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]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.