2011-12-10 9 views
7

मेरे पास युगल के साथ युगल के रूप में मूल्य और स्ट्रिंग के रूप में एक शब्दकोश है।शब्दकोश में अद्वितीय मूल्यों की घटनाओं को कैसे गिनें?

मैं इस शब्दकोश में प्रत्येक मान की घटनाओं को गिनना चाहता हूं और मैं यह मान जानना चाहता हूं (उदाहरण के लिए दोहराया गया है)।

उदाहरण के लिए

:

key1, 2 
key2, 2 
key3, 3 
key4, 2 
key5, 5 
key6, 5 

मैं एक सूची प्राप्त करना चाहते हैं:

2 - 3 (times) 
3 - 1 (once) 
5 - 2 (twice) 

मैं इसे कैसे कर सकता है?

+1

एक छोटे से अधिक जानकारी: आप कर रहे हैं उन मानों की गिनती पूछना जिन्हें दोहराया नहीं जाता है? क्या आप हमें डेटा, और वांछित आउटपुट का उदाहरण दे सकते हैं? – Alan

+5

समानता के लिए परीक्षण युगल एक बहुत संदिग्ध अभ्यास है। यदि आप उत्तर चाहते हैं तो आप इसका उल्लेख करने से बचना चाहेंगे। लिंक की विशिष्टता का उपयोग करना()। मूल्य संपत्ति पर गणना() अन्यथा एक ऐसा दृष्टिकोण है जो आपके टैग से मेल खाता है। –

+2

और आप यहां युगल की समानता का परीक्षण कैसे करना चाहते हैं? –

उत्तर

9

ध्यान देने वाली पहली बात यह है कि आप वास्तव में शब्दकोश की कुंजी के बारे में परवाह नहीं करते हैं। इसलिए कदम एक हाथ में काम के लिए अप्रासंगिक के रूप में उन्हें अनदेखा करना है। हम शब्दकोश की Values संपत्ति के साथ काम करने जा रहे हैं, और यह काम पूर्णांक के किसी भी अन्य संग्रह (या वास्तव में किसी भी अन्य प्रकार के किसी अन्य प्रकार के समान है जो हम समानता के लिए तुलना कर सकते हैं) के समान ही है।

इस समस्या के दो आम दृष्टिकोण हैं, जिनमें से दोनों जानकारियों के लायक हैं।

पहले एक और शब्दकोश का उपयोग करता मूल्यों की गिनती धारण करने के लिए:

//Start with setting up the dictionary you described. 
Dictionary<string, int> dict = new Dictionary<string, int>{ 
    {"key1", 2}, 
    {"key2", 2}, 
    {"key3", 3}, 
    {"key4", 2}, 
    {"key5", 5}, 
    {"key6", 5} 
}; 
//Create a different dictionary to store the counts. 
Dictionary<int, int> valCount = new Dictionary<int, int>(); 
//Iterate through the values, setting count to 1 or incrementing current count. 
foreach(int i in dict.Values) 
    if(valCount.ContainsKey(i)) 
     valCount[i]++; 
    else 
     valCount[i] = 1; 
//Finally some code to output this and prove it worked: 
foreach(KeyValuePair<int, int> kvp in valCount)//note - not sorted, that must be added if needed 
    Console.WriteLine("{0} - {1}", kvp.Key, kvp.Value); 

उम्मीद है कि यह बहुत सरल है। एक और दृष्टिकोण और अधिक जटिल है, लेकिन कुछ प्लस है:

//Start with setting up the dictionary you described. 
Dictionary<string, int> dict = new Dictionary<string, int>{ 
    {"key1", 2}, 
    {"key2", 2}, 
    {"key3", 3}, 
    {"key4", 2}, 
    {"key5", 5}, 
    {"key6", 5} 
}; 
IEnumerable<IGrouping<int, int>> grp = dict.Values.GroupBy(x => x); 
//Two options now. One is to use the results directly such as with the 
//equivalent code to output this and prove it worked: 
foreach(IGrouping<int, int> item in grp)//note - not sorted, that must be added if needed 
    Console.WriteLine("{0} - {1}", item.Key, item.Count()); 
//Alternatively, we can put these results into another collection for later use: 
Dictionary<int, int> valCount = grp.ToDictionary(g => g.Key, g => g.Count()); 
//Finally some code to output this and prove it worked: 
foreach(KeyValuePair<int, int> kvp in valCount)//note - not sorted, that must be added if needed 
    Console.WriteLine("{0} - {1}", kvp.Key, kvp.Value); 

(हम शायद बल्कि वर्बोज़ IEnumerable<IGrouping<int, int>> से var का उपयोग करेंगे, लेकिन यह सटीक किया जा रहा है जब कोड समझा लायक है)।

सीधी तुलना में, यह संस्करण कम है - समझने और कम कुशल दोनों को अधिक जटिल। हालांकि, इस दृष्टिकोण को सीखना एक ही तकनीक के कुछ संक्षिप्त और कुशल रूपों के लिए अनुमति देता है, इसलिए यह जांच करने लायक है।

GroupBy() एक गणना लेता है और एक और गणना बनाता है जिसमें कुंजी-मूल्य जोड़े होते हैं जहां मान भी एक गणना है। लैम्ब्डा x => x का मतलब है कि इसे समूहीकृत किया गया है, लेकिन हमारे पास अलग-अलग समूह नियमों के लिए flexibilty है। grp की सामग्री को एक सा दिखाई देता है:

{ 
    {Key=2, {2, 2, 2}} 
    {Key=3, {3}} 
    {Key=5, {5, 5}} 
} 

तो, हम प्रत्येक समूह हम Key बाहर निकालते हैं और समूह पर Count() फोन के लिए यह एक के माध्यम से लूप, हम परिणाम हम चाहते हैं।

अब, पहले मामले में हमने एक ही ओ (एन) पास में हमारी गिनती का निर्माण किया, जबकि यहां हम ओ (एन) पास में समूह का निर्माण करते हैं, और फिर दूसरी ओ (एन) में गिनती प्राप्त करते हैं।) पास, इसे बहुत कम कुशल बनाते हैं। यह समझना थोड़ा मुश्किल है, तो इसका जिक्र क्यों करना है?

IEnumerable<IGrouping<int, int>> grp = dict.Values.GroupBy(x => x); 
foreach(IGrouping<int, int> item in grp) 
    Console.WriteLine("{0} - {1}", item.Key, item.Count()); 

में:

foreach(var item in dict.Values.GroupBy(x => x)) 
    Console.WriteLine("{0} - {1}", item.Key, item.Count()); 

कौन सा काफी संक्षिप्त है, और मुहावरेदार हो जाता है

ठीक है, पहला यह है कि एक बार हम यह समझते हैं हम लाइनों बदल सकते है।यह विशेष रूप से अच्छा है अगर हम आगे बढ़ना चाहते हैं और मूल्य-गणना जोड़े के साथ कुछ और जटिल बनाते हैं क्योंकि हम इसे किसी अन्य ऑपरेशन में जोड़ सकते हैं।

संस्करण एक शब्दकोश में परिणाम डालता है और भी अधिक अभी भी संक्षिप्त होना कर सकते हैं: पहले के लिए

var valCount = dict.Values.GroupBy(x => x).ToDictionary(g => g.Key, g => g.Count()); 

वहाँ, अपने पूरे प्रश्न एक छोटी लाइन में उत्तर दिया, बल्कि 6 (बाहर काटने टिप्पणियाँ) की तुलना में संस्करण।

(कुछ dict.GroupBy(x => x.Value) साथ dict.Values.GroupBy(x => x) को बदलने के लिए जो वास्तव में एक ही परिणाम होगा एक बार हम इस पर Count() चलाने पसंद कर सकते हैं। आप तुरंत सुनिश्चित नहीं हैं क्यों, इस पर काम करने की कोशिश)।

दूसरा लाभ यह है कि हमारे पास अन्य मामलों में GroupBy के साथ अधिक लचीलापन है। इन कारणों से, GroupBy का उपयोग करने के लिए उपयोग किए जाने वाले लोग dict.Values.GroupBy(x => x).ToDictinary(g => g.Key, g => g.Count()); की एक-पंक्ति समाप्ति के साथ शुरू होने की संभावना रखते हैं और फिर अधिक वर्बोज़ में बदल जाते हैं लेकिन पहले संस्करण के अधिक प्रभावशाली रूप (जहां हम नए शब्दकोश में कुल योग बढ़ाते हैं)) अगर यह एक प्रदर्शन हॉटस्पॉट साबित हुआ।

-1

भी आसान हो जाएगा:

Private Function CountOccurenceOfValue(dictionary As Dictionary(Of Integer, Integer), valueToFind As Integer) As Integer 
    Return (From temp In dictionary Where temp.Value.Equals(valueToFind) Select temp).Count() 
End Function 

(हाँ, यह VB.NET में है, लेकिन आप ज्यादा मुसीबत सी # :-) कन्वर्ट करने के लिए नहीं होना चाहिए)

+0

उपयोगकर्ता सी # के लिए पूछ रहा है, और इस प्रकार उत्तर सी # में प्रस्तुत किया जाना चाहिए। – Neeko

संबंधित मुद्दे