2010-01-26 8 views
74

मैंने शून्य की जांच करने की कोशिश की लेकिन संकलक चेतावनी देता है कि यह स्थिति कभी नहीं होगी। मुझे क्या खोजना चाहिए?सी # डिक्शनरी <int, int> लुकअप का क्या होता है यदि कुंजी मौजूद नहीं है?

उत्तर

138

मान लिया जाये कि आप लाभ प्राप्त करना चाहते है, तो कुंजी मौजूद नहीं है, 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 बीच एक बड़ा अंतर है।)

+0

@ जोनस्केट कोशिश नहीं कर रहा है गेटवैल्यू भी एक डबल लुकअप कर रहा है ([जैसा कि इस प्रश्न शरीर में बताया गया है] (http://stackoverflow.com/questions/1413304/net-adding-dictionary-item-check-if-it-exists- या-अनुमति देते हैं-अपवाद))? – nawfal

+2

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

+0

निष्क्रिय, मैं शून्य की उम्मीद करता रहा, लेकिन शब्दकोश के लिए, यह enum में समतुल्य "0" देता है। – Jess

7

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

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

, जॉन स्कीट के जवाब में वर्णित के रूप TryGetValue विधि का उपयोग ।

+5

TryGet बेहतर है –

+2

Coz आप hashtable के माध्यम से प्रमुख देखने दो बार के समाधान कर रहे हैं तो आप तुरंत बाद शामिल हो जाओ। Wintellect PowerCollections में 'GetValueElseAdd' विधियां भी हैं जिन्हें आप मान देते हैं (या एक' Func ') यदि आप वहां नहीं जा रहे हैं तो सम्मिलित करने पर संकल्प को सहेजने के लिए भी एक मूल्य दें। मुझे लगता है कि इसे .NET libs में नहीं बनाया गया है क्योंकि यदि आप इसे कैश स्टाइल में उपयोग कर रहे हैं तो जोड़ें पथ कम बार होता है] –

+0

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

2

आपको मूल्य को निकालने का प्रयास करने से पहले शब्दकोश .ContainsKey (int कुंजी) की जांच करनी चाहिए।

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

के लिए छोड़ दूंगा क्यों आप इसे दो बार लुकअप करना चाहते हैं? –

+1

@ जोन क्योंकि यह आमतौर पर बेहतर – mookid8000

+2

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

0

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

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

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

+1

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

+0

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

18

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

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

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

+0

अतिरिक्त जानकारी एमएसडीएन में मिल सकती है: http://msdn.microsoft.com/en-gb/library/9tee9ht2.aspx – cyberzed

-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; 
    } 
} 
संबंधित मुद्दे