स्विफ्ट में दो शब्दकोश उदाहरणों को कैसे मिलाएं?


87

मैं Dictionaryएक Dictionaryका उपयोग करके दूसरे को कैसे जोड़ूं Swift?

मैं AlamoFireलाइब्रेरी का उपयोग कर रहा हूं ए JSONको भेजने के लिए 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लेकिन एक संकलित त्रुटि मिली है:

बाइनरी ऑपरेटर '+' को दो '[स्ट्रिंग: AnyObject]' ऑपरेंड पर लागू नहीं किया जा सकता है




अरे @-खानाबदोश, क्या आप अपने स्वीकृत उत्तर को दोगुने से अधिक के साथ स्थानांतरित कर सकते हैं - कृपया :-)?
ब्लैकजैक्स

जवाबों:


67
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/life/ift


मैं इसे अपने कोड में कहीं भी उपलब्ध extensionहोने के लिए कहां रख सकता हूं function? माफ करना मैं एक noob हूँ!
नोमैड

1
इसे अपने प्रोजेक्ट में किसी भी फाइल में रखें
Shuo

क्या होगा यदि मूल्य भी एक शब्दकोश है, तो आप कैसे गहरा विलय करते हैं?
रॉड्रिगो रूइज़

@RodrigoRuiz मुझे नहीं लगता कि इससे कोई फर्क पड़ता है, जब तक कि आपका मूल शब्दकोष भी वैसा ही आर्किटेक्चर नहीं है, इससे कोई फर्क नहीं पड़ेगा (जब तक कि मूल शब्दकोश टाइप का न हो [Key: Any])
सेप्ट्रॉनिक

2
Dictionaryअपने मर्ज के फ़ंक्शंस मिलने के बाद से अब एक्सटेंशन की ज़रूरत नहीं है । Stackoverflow.com/a/43615143/971329 देखें ।
ब्लैकजैक्स

161

मुझे यह तरीका पसंद है:

dicFrom.forEach { (key, value) in dicTo[key] = value }

स्विफ्ट 4 और 5

स्विफ्ट 4 के साथ ऐप्पल ने दो शब्दकोशों को मर्ज करने के लिए एक बेहतर तरीका पेश किया:

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]

आपके पास यहां 2 विकल्प हैं (जैसे कि कंटेनर पर काम करने वाले अधिकांश कार्य):

  • merge एक मौजूदा शब्दकोश को बदल देता है
  • merging एक नया शब्दकोश देता है

16

स्विफ्ट के लिए = = 2.2:
let parameters = dict1.reduce(dict2) { r, e in var r = r; r[e.0] = e.1; return r }

स्विफ्ट के लिए <2.2:
let parameters = dict1.reduce(dict2) { (var r, e) in r[e.0] = e.1; return r }

स्विफ्ट 4 में एक नया कार्य है: let parameters = dict1.reduce(into: dict2) { (r, e) in r[e.0] = e.1 }

यह मानक पुस्तकालय के आसपास खुदाई करने के लिए वास्तव में महत्वपूर्ण है: map, reduce, dropFirst, forEachआदि संक्षिप्त कोड के स्टेपल कर रहे हैं। कार्यात्मक बिट्स मजेदार हैं!


स्विफ्ट 2.2 संकलक एक चेतावनी फेंकता है: "'var' मापदंडों को हटा दिया गया है और स्विफ्ट 3 में हटा दिया जाएगा"
धीरज वेपकोमा

8
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]

7

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

6

हम मर्ज कीवर्ड का उपयोग करके शब्दकोशों को बेहतर तरीके से मर्ज कर सकते हैं

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]

3

मेरी ज़रूरतें अलग थीं, मैं विलीन होना चाहता था और क्लोब नहीं करना चाहता था।

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

इस दृष्टिकोण का प्रयास करें

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

}

आशा है कि इससे सहायता मिलेगी !!


1

स्विफ्ट में दो शब्दकोश उदाहरणों को संयोजित करने के लिए आप नीचे दिए गए कोड का उपयोग कर सकते हैं:

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

-1

आप शब्दकोश को घोषित करने के लिए कीवर्ड का उपयोग कर रहे हैं ताकि आप अपने शब्दकोश में परिवर्तन न कर सकें क्योंकि इसका उपयोग निरंतर घोषित करने के लिए किया जाता है।

इसे var keyword में बदलें फिर यह आपके लिए काम करेगा।

var dict1: [String: AnyObject] = [
            kFacebook: [
                kToken: token
            ]
        ]

var dict2: [String: AnyObject] = [
        kRequest: [
            kTargetUserId: userId
        ]
    ]

dict1 += dict2
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.