यदि कुंजी मौजूद नहीं है तो C # Dictionary <int, int> लुकअप क्या होता है?


121

मैंने अशक्त की जाँच करने की कोशिश की लेकिन संकलक ने चेतावनी दी कि यह स्थिति कभी नहीं होगी। मुझे क्या खोजना चाहिए?

जवाबों:


196

मान लें कि आप कुंजी अगर लाभ प्राप्त करना चाहते करता है अस्तित्व, उपयोग Dictionary<TKey, TValue>.TryGetValue:

int value;
if (dictionary.TryGetValue(key, out value))
{
    // Key was in dictionary; "value" contains corresponding value
} 
else 
{
    // Key wasn't in dictionary; "value" is now 0
}

(का उपयोग करते हुए ContainsKeyऔर फिर अनुक्रमणिका कुंजी को दो बार देखती है, जो कि बहुत व्यर्थ है।)

ध्यान दें कि भले ही आप संदर्भ प्रकारों का उपयोग कर रहे थे , अशक्त के लिए जाँच से काम नहीं चलेगा - Dictionary<,>यदि आप अनुपलब्ध कुंजी का अनुरोध करते हैं, तो अशक्त वापस लौटने के बजाय, अनुक्रमणिका एक अपवाद फेंक देगी। (यह Dictionary<,>और के बीच एक बड़ा अंतर है Hashtable।)


@JonSkeet TryGetValue एक डबल लुकअप भी नहीं कर रहा है ( जैसा कि इस प्रश्न निकाय में कहा गया है )?
नवाफाल

5
@nawfal: मुझे कोई संकेत नहीं दिखता है कि यह सवाल बताता है। यह कहता है कि यह अधिक काम कर रहा है ContainsKey, जो सच है, क्योंकि इसे मूल्य भी निकालना है। हालांकि यह दो लुकअप नहीं कर रहा है।
जॉन स्कीट

स्वाभाविक रूप से, मैं अशक्त होने की उम्मीद करता रहा, लेकिन डिक्शनरी <TKey, enum> के लिए, यह एनम में "0" के बराबर रिटर्न देता है।
जेस

23

शब्दकोश ने KeyNotFoundइस घटना में एक अपवाद फेंका कि शब्दकोश में आपकी कुंजी नहीं है।

जैसा कि सुझाव दिया गया है, ContainsKeyउपयुक्त एहतियात है। TryGetValueभी प्रभावी है।

यह शब्दकोश को अधिक प्रभावी ढंग से शून्य के मूल्य को संग्रहीत करने की अनुमति देता है। इस तरह से व्यवहार किए बिना, [] ऑपरेटर से एक अशक्त परिणाम के लिए जाँच करना या तो एक शून्य मान या इनपुट कुंजी की गैर-मौजूदगी को इंगित करेगा जो अच्छा नहीं है।


अतिरिक्त जानकारी MSDN: msdn.microsoft.com/en-gb/library/9tee9ht2.aspx
साइबर

10

यदि आप एक नया मान जोड़ने का प्रयास करने से पहले जांच कर रहे हैं, तो ContainsKeyविधि का उपयोग करें :

if (!openWith.ContainsKey("ht"))
{
    openWith.Add("ht", "hypertrm.exe");
}

यदि आप जाँच रहे हैं कि मान मौजूद है, तो TryGetValueजॉन स्कीट के उत्तर में वर्णित विधि का उपयोग करें ।


8
ट्राईगेट बेहतर है
बार्टनेल

2
Coz आप दो बार हैशटेबल के माध्यम से कुंजी लुकअप को हल कर रहे हैं यदि आप तुरंत शामिल हो जाते हैं। Wintellect PowerCollections में वे GetValueElseAddविधियाँ भी होती हैं जो आप मूल्य (या a Func<TValue>) को सम्मिलित करने के लिए रिज़ॉल्यूशन को बचाने के लिए देते हैं यदि आप जोड़ने जा रहे हैं यदि इसके नहीं हैं। मुझे लगता है कि इस कारण से यह .NET .NETs में नहीं आया है क्योंकि ऐड रास्ता कम होने के कारण यदि आप इसे कैश स्टाइल में उपयोग कर रहे हैं]
रूबेन बार्टेलिंक

@rub: मुझे लगता है कि कोड के उद्देश्य पर निर्भर करता है। यदि आप उस मूल्य का उपयोग करना चाहते हैं जो मैं मानता हूं कि TryGetValueबेहतर होगा, लेकिन अगर आप यह जांचना चाहते हैं कि डुप्लिकेट परिवर्धन से बचने के लिए शब्दकोश में कुंजी है या नहीं, तो मैं कहूंगा कि ContainsKeyबस उतना ही अच्छा है (यदि बेहतर नहीं है)।
फ्रेड्रिक मोर

@ फ़्रेड्रिक: यदि आप केवल एक जांच करना चाहते हैं, तो हाँ, यह ContainsKey का उपयोग करने के लायक है। ध्यान दें कि इस उत्तर के नमूना कोड में ऐसा नहीं है।
जॉन स्कीट

@Jon: सच है, मैं वास्तव में याद किया है कि जोड़ा मूल्य तुरंत जोड़ा गया था के बाद।
फ्रेड्रिक मोर

3

मूल्य निकालने की कोशिश करने से पहले आपको Dictionary.CtaintainsKey (int key) की जांच करनी चाहिए।

Dictionary<int, int> myDictionary = new Dictionary<int, int>();
myDictionary.Add(2,4);
myDictionary.Add(3,5);

int keyToFind = 7;
if(myDictionary.ContainsKey(keyToFind))
{
    myValueLookup = myDictionay[keyToFind];
    // do work...
}
else
{
    // the key doesn't exist.
}

2
आप इसे दो बार लुकअप क्यों करना चाहते हैं?
जॉन स्कीट

2
@ मुक्कीद: मेरी राय में नहीं। यह विचार है कि कुंजी को देखने की कोशिश करें, और यदि यह पाया जाता है, तो कार्रवाई का एक कोर्स करें, और कार्रवाई का एक और कोर्स अन्यथा, सही?
जॉन स्कीट

3
@Jon - ईमानदारी से? क्योंकि मुझे पता नहीं था TryGetValue। शुक्र है, मैं अब ऐसा करता हूं, इसलिए मुझे भविष्य में पता चल जाएगा। मैं इस उत्तर को अक्षुण्ण रखने जा रहा हूं, हालांकि 'चर्चा महान है।
ज़ोंबीशेप

@ जोंन स्कीट - यह मैं यहाँ क्यों हूँ। :)
ZombieSheep

@JonSkeet क्योंकि C # 7 से पहले, आप TryGetValueएक लैम्ब्डा अभिव्यक्ति में उपयोग नहीं कर सकते । हालांकि इससे मुझे लगता है कि C # के लिए एक नया विस्तार एक catchऑपरेटर के समान nullऑपरेटर होगा।
नेटमैज

1

एक सहायक वर्ग आसान है:

public static class DictionaryHelper
{
    public static TVal Get<TKey, TVal>(this Dictionary<TKey, TVal> dictionary, TKey key, TVal defaultVal = default(TVal))
    {
        TVal val;
        if( dictionary.TryGetValue(key, out val) )
        {
            return val;
        }
        return defaultVal;
    }
}

कभी-कभी मुझे आश्चर्य होता है कि इस isn को मानक पुस्तकालय में क्यों जोड़ा गया। यदि कोई प्रविष्टि नहीं है, तो लगभग सभी भाषाएं जो हैशमैप का उपयोग करती हैं, तो कोई अपवाद नहीं है। आपके शब्दकोश में मौजूद कोई आइटम असाधारण व्यवहार नहीं है।
एडम हेस

@AdamHess - यही कारण है कि आपके पास हैशटेबल () में c # ... दुर्भाग्य से, आपकी चाबियाँ वहां बॉक्सिंग हो जाती हैं ... :(
veljkoz

0

ContainsKey वह है जो आप खोज रहे हैं।


0

आपको शायद उपयोग करना चाहिए:

if(myDictionary.ContainsKey(someInt))
{
  // do something
}

आप अशक्त के लिए जाँच क्यों नहीं कर सकते इसका कारण यह है कि यहाँ कुंजी एक मूल्य प्रकार है।


1
मान का प्रकार कुछ हद तक अप्रासंगिक है, क्योंकि अशक्त के लिए जाँच से वांछित प्रभाव नहीं होगा।
जॉन स्कीट

@ जोहान्स, जॉन का समाधान निश्चित रूप से बेहतर है, लेकिन पूछने वाले ने कहा कि उसने जांच की कि क्या कुंजी मौजूद है, और यह एक शब्दकोश है <int, int>, इसलिए कुंजी भी एक मूल्य प्रकार है।
रज्जी

0
int result= YourDictionaryName.TryGetValue(key, out int value) ? YourDictionaryName[key] : 0;

यदि कुंजी शब्दकोश में मौजूद है, तो यह कुंजी का मान लौटाता है अन्यथा यह 0 देता है।

आशा है, यह कोड आपकी मदद करता है।


1
यदि कुंजी मौजूद है, तो यह कोड दो बार दिखाई देगा। TryGetValueपर्याप्त है, valueइसके बजाय का उपयोग करेंresult
Mathieu VIALES

0

इस विशेष शब्दकोश को इनकैप्सुलेट करने के विकल्प पर विचार करें और उस कुंजी का मान लौटाने के लिए एक विधि प्रदान करें:

public static class NumbersAdapter
{
    private static readonly Dictionary<string, string> Mapping = new Dictionary<string, string>
    {
        ["1"] = "One",
        ["2"] = "Two",
        ["3"] = "Three"
    };

    public static string GetValue(string key)
    {
        return Mapping.ContainsKey(key) ? Mapping[key] : key;
    }
}

तब आप इस शब्दकोश के व्यवहार का प्रबंधन कर सकते हैं।

यहाँ उदाहरण के लिए: यदि शब्दकोश में कुंजी नहीं है, तो यह कुंजी है कि आप पैरामीटर से गुजरते हैं।

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