यह निर्धारित करना कि स्विफ्ट शब्दकोश में कुंजी है और इसके किसी भी मान को प्राप्त करना


260

मैं वर्तमान में निम्नलिखित (अनाड़ी) कोड के टुकड़ों का उपयोग कर रहा हूं ताकि यह निर्धारित किया जा सके कि एक (गैर-खाली) स्विफ्ट शब्दकोश में एक दी गई कुंजी है और उसी शब्दकोश से एक (किसी भी) मूल्य प्राप्त करने के लिए।

स्विफ्ट में कोई और अधिक सुरुचिपूर्ण ढंग से कैसे डाल सकता है?

// excerpt from method that determines if dict contains key
if let _ = dict[key] {
    return true
}
else {
    return false
}

// excerpt from method that obtains first value from dict
for (_, value) in dict {
    return value
}

आप उपयोग कर सकते हैं indexForKeyयदि आपको लगता है कि यह स्पष्ट और अधिक स्पष्ट है; stackoverflow.com/a/29299943/294884
फटी डे

अक्सर आप क्या चाहते हैं मूल रूप से है: यहां मूल रूप से मतलब है "ऐसी कोई कुंजी है या नहीं, एक खाली लौटने"। cityName:String = dict["city"] ?? ""?? ""
fattie

जवाबों:


480

आपको ऐसा करने के लिए किसी विशेष कोड की आवश्यकता नहीं है , क्योंकि यह वही है जो पहले से ही एक शब्दकोश है। जब आप जानते हैं कि dict[key]आपको पता है कि क्या शब्दकोश में कुंजी है, क्योंकि जो वैकल्पिक आपको वापस मिलता है वह नहीं है nil(और इसमें मूल्य शामिल है)।

इसलिए, यदि आप सिर्फ सवाल शब्दकोश कुंजी है कि क्या उत्तर देना चाहते हैं, पूछते हैं:

let keyExists = dict[key] != nil

यदि आप मूल्य चाहते हैं और आपको पता है कि शब्दकोश में कुंजी है, तो कहें:

let val = dict[key]!

लेकिन अगर, जैसा कि आमतौर पर होता है, आप नहीं जानते कि इसमें कुंजी है - आप इसे लाना चाहते हैं और इसका उपयोग करना चाहते हैं, लेकिन केवल अगर यह मौजूद है - तो कुछ का उपयोग करें if let:

if let val = dict[key] {
    // now val is not nil and the Optional has been unwrapped, so use it
}

6
मैं अनुसरण नहीं करता। मैंने सिर्फ एक मूल्य (दो बार) प्राप्त किया। आपको और क्या चाहिए?
मैट

"पहले मूल्य" जैसी कोई चीज नहीं है; एक शब्दकोश अनियंत्रित है। यदि आप केवल मान चाहते हैं, बिना कुंजियों के, तो कहना dict.values
मैट

1
dict.valuesअपारदर्शी होने के कारण सावधान रहें । आप इसे पूरा कर सकते हैं लेकिन यह सब है। (ठीक है, यह सब नहीं है, लेकिन मुझे मज़ाक करना है।) यदि आप चाहते हैं कि यह एक ऐरे के लिए पुनः प्राप्त हो, तो लें dict.values.array
मैट

1
@bubakazouba यह कोशिश करें: let d = ["hey":"ho"]; let s = d["hey"]; print(s)यह एक वैकल्पिक है, जैसे यह हमेशा से रहा है।
मैट

1
@ सकल यह एक बहुत गहरा सवाल है, लेकिन इसलिए इसे अलग से पूछें।
मैट

68

क्यों नहीं बस के लिए जाँच करें dict.keys.contains(key)? dict[key] != nilउन मामलों में जाँच करना काम नहीं करेगा जहाँ मूल्य शून्य है। [String: String?]उदाहरण के लिए एक शब्दकोश के साथ ।


2
या सिर्फ लिखने के बजाय if let val = dict[key]आप if let val = dict[key] as? Stringइस मामले में उपयोग कर सकते हैं ।
Okhan Okbay

.keys.contains यह बताने में मदद नहीं करता है कि क्या कुंजी मौजूद है, या यदि मान शून्य है। शायद पहले के स्विफ्ट संस्करणों में? मेरे लिए तेजी से काम नहीं करता है 4.
रोवन गोंटियर

8
यह संभावित रूप से बहुत बेकार है, क्योंकि (1) आप कॉल करते हैं dict.keysजो सभी कुंजियों के साथ एक सरणी बनाता है, तब (2) क्रम में हर कुंजी की जांच करता है जब तक कि आप एक (या कोई नहीं!) ढूंढते हैं। मुझे पता है कि तुम एक के मामले को संबोधित करने की कोशिश कर रहे हैं [String: String?], लेकिन उस समाधान के साथ बहुत सावधान रहना होगा ...
चर

3
जैसा कि @charles ने उल्लेख किया है, यह तेजी से देखने के लाभ को समाप्त कर देगा जो एक शब्दकोश का उपयोग करता है ताकि मैं इस एक के खिलाफ सलाह दूं, लेकिन फिर भी निश्चित रूप से एक वैध विकल्प है।
व्यावसायिक

4
आपको इस पद्धति का उपयोग कभी नहीं करना चाहिए , सैद्धांतिक की बजाय जटिलता ओ (एन) में है (हैश फ़ंक्शन कार्यान्वयन पर निर्भर करता है) ओ (1) प्रत्यक्ष शब्दकोश का उपयोग।
क्रिप्ट

45

let keyExists = dict[key] != nilयदि डिक्शनरी में कुंजी शामिल है, लेकिन स्वीकृत मूल्य शून्य नहीं होगा।

यदि आप यह सुनिश्चित करना चाहते हैं कि डिक्शनरी में इसके उपयोग की कुंजी नहीं है (स्विफ्ट 4 में परीक्षण)।

if dict.keys.contains(key) {
  // contains key
} else { 
  // does not contain key
}

3
यह हान के उत्तर के समान है।
डेक्कन मैककेना

1
चेकिंग == nilकार्य करता है, भले ही शब्दकोश में वैकल्पिक मान हों। ऐसा इसलिए है क्योंकि लुकअप परिणाम को एक के रूप में लपेटा जाता है Optional। दूसरी ओर, यह जांचने के लिए कि क्या देखा गया मूल्य वास्तव में nilअनुपस्थित के बजाय है, आप उपयोग कर सकते हैं == .some(nil)
jedwidz

1
मैं अन्य विधियों के O (1) लुकअप की तुलना में इस विधि का उपयोग करने की दक्षता जोड़ूंगा। मेरा मानना ​​है कि यह O (n) लुकअप है
अल्बर्टो वेगा

1
@ AlbertoVega-MSFT यह है O(1)। इसे भी देखें: github.com/apple/swift-evolution/blob/master/proposals/… आपने क्या सोचा कि यह क्या था O(n)?
अलेक्जेंडर - मोनिका

1
यहांDictionary.Keys.contains(...) फ़ंक्शन के लिए प्रलेखन का कहना है कि इसमें O(n)जटिलता है, जहां nअनुक्रम की लंबाई है।
आदिल हुसैन

5

ऐसा लगता है कि आपको @matt से क्या चाहिए, लेकिन अगर आप एक कुंजी के लिए एक मूल्य प्राप्त करने के लिए एक त्वरित तरीका चाहते हैं, या बस पहला मान यदि वह कुंजी मौजूद नहीं है:

extension Dictionary {
    func keyedOrFirstValue(key: Key) -> Value? {
        // if key not found, replace the nil with 
        // the first element of the values collection
        return self[key] ?? first(self.values)
        // note, this is still an optional (because the
        // dictionary could be empty)
    }
}

let d = ["one":"red", "two":"blue"]

d.keyedOrFirstValue("one")  // {Some "red"}
d.keyedOrFirstValue("two")  // {Some "blue"}
d.keyedOrFirstValue("three")  // {Some "red”}

ध्यान दें, इस बात की कोई गारंटी नहीं है कि वास्तव में आपको पहले मूल्य के रूप में क्या मिलेगा, यह सिर्फ इस मामले में होता है कि "लाल" वापस करना है।


1
??ऑपरेटर के अच्छे उपयोग ने मेरा सुविधा समाधान मुझसे ले लिया, लेकिन एक विस्तार के रूप में डिफ़ॉल्ट मान डेटा असुरक्षा या अप्रत्याशित व्यवहार पेश कर सकता है। ऐसा लगता है जैसे कुछ ठोस उपवर्ग Dictionaryको रोजगार चाहिए। nilस्थिति विशिष्ट कार्यक्षमता को छोड़कर किसी रिटर्न के मामले में आपको कितनी बार पहले मूल्य की आवश्यकता होती है?
नूडलऑफडॉट


0

वैकल्पिक NSAttributedString स्टोर करने वाले कैश कार्यान्वयन के लिए मेरा समाधान:

public static var attributedMessageTextCache    = [String: NSAttributedString?]()

    if attributedMessageTextCache.index(forKey: "key") != nil
    {
        if let attributedMessageText = TextChatCache.attributedMessageTextCache["key"]
        {
            return attributedMessageText
        }
        return nil
    }

    TextChatCache.attributedMessageTextCache["key"] = .some(.none)
    return nil

0

यहाँ स्विफ्ट 3 पर मेरे लिए क्या काम है

let _ = (dict[key].map { $0 as? String } ?? "")
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.