c# - आप मूल्य से एक शब्दकोश कैसे सॉर्ट करते हैं?




.net sorting (12)

LINQ का प्रयोग करें:

Dictionary<string, int> myDict = new Dictionary<string, int>();
myDict.Add("one", 1);
myDict.Add("four", 4);
myDict.Add("two", 2);
myDict.Add("three", 3);

var sortedDict = from entry in myDict orderby entry.Value ascending select entry;

यह भी महान लचीलेपन के लिए अनुमति देगा कि आप शीर्ष 10, 20 10%, आदि का चयन कर सकते हैं या यदि आप type-ahead StartsWith लिए अपने शब्द आवृत्ति सूचकांक का उपयोग कर रहे हैं, तो आप StartsWith क्लॉज़ को भी शामिल कर सकते हैं।

मुझे अक्सर एक शब्द को क्रमबद्ध करना होता है, जिसमें मूल्य के आधार पर कुंजी और मान शामिल होते हैं। उदाहरण के लिए, मेरे पास शब्दों और संबंधित आवृत्तियों का एक हैश है, जिसे मैं आवृत्ति द्वारा ऑर्डर करना चाहता हूं।

एक SortedList जो एकल मान (आवृत्ति कहें) के लिए अच्छा है, कि मैं इसे शब्द में वापस मैप करना चाहता हूं।

कुंजी द्वारा SortedDictionary आदेश, मूल्य नहीं। कुछ एक कस्टम वर्ग का सहारा लेते हैं, लेकिन क्या एक क्लीनर तरीका है?


VB.NET का उपयोग करके एक ListView नियंत्रण में बाँधने के लिए एक क्रमबद्धता सूची को क्रमबद्ध करना:

Dim MyDictionary As SortedDictionary(Of String, MyDictionaryEntry)

MyDictionaryListView.ItemsSource = MyDictionary.Values.OrderByDescending(Function(entry) entry.MyValue)

Public Class MyDictionaryEntry ' Need Property for GridViewColumn DisplayMemberBinding
    Public Property MyString As String
    Public Property MyValue As Integer
End Class

XAML:

<ListView Name="MyDictionaryListView">
    <ListView.View>
        <GridView>
            <GridViewColumn DisplayMemberBinding="{Binding Path=MyString}" Header="MyStringColumnName"></GridViewColumn>
            <GridViewColumn DisplayMemberBinding="{Binding Path=MyValue}" Header="MyValueColumnName"></GridViewColumn>
         </GridView>
    </ListView.View>
</ListView>

आप कभी भी किसी शब्दकोश को छाँटने में सक्षम नहीं होंगे। वे वास्तव में आदेशित नहीं हैं। एक शब्दकोश के लिए गारंटी यह है कि कुंजी और मूल्य संग्रह चलने योग्य हैं, और मूल्यों को सूचकांक या कुंजी द्वारा पुनर्प्राप्त किया जा सकता है, लेकिन किसी विशेष आदेश की कोई गारंटी नहीं है। इसलिए आपको एक सूची में नाम मूल्य जोड़ी प्राप्त करने की आवश्यकता होगी।


आप किसी डिक्शनरी को वैल्यू के आधार पर सॉर्ट कर सकते हैं और उसे अपने आप में सहेज सकते हैं (ताकि जब आप उस पर आगे बढ़ते हैं तो ऑर्डर में वैल्यू निकल आए):

dict = dict.OrderBy(x => x.Value).ToDictionary(x => x.Key, x => x.Value);

यकीन है, यह सही नहीं हो सकता है, लेकिन यह काम करता है।


आप डिक्शनरी में प्रविष्टियों को क्रमबद्ध नहीं करते हैं। .NET में डिक्शनरी क्लास को हैशटेबल के रूप में लागू किया गया है - यह डेटा संरचना परिभाषा के अनुसार क्रमबद्ध नहीं है।

यदि आपको अपने संग्रह (कुंजी द्वारा) को पुनरावृत्त करने में सक्षम होने की आवश्यकता है - आपको सॉर्टेडबेडर का उपयोग करने की आवश्यकता है, जिसे बाइनरी ट्री ट्री के रूप में लागू किया गया है।

आपके मामले में, हालांकि स्रोत संरचना अप्रासंगिक है, क्योंकि यह एक अलग क्षेत्र द्वारा सॉर्ट किया गया है। आपको फिर भी इसे आवृत्ति द्वारा क्रमबद्ध करना होगा और इसे संबंधित क्षेत्र (आवृत्ति) द्वारा छांटे गए नए संग्रह में रखना होगा। तो इस संग्रह में आवृत्तियाँ कुंजियाँ हैं और शब्द मान हैं। चूँकि कई शब्दों की आवृत्ति समान हो सकती है (और आप इसे एक कुंजी के रूप में उपयोग करने जा रहे हैं) आप न तो डिक्शनरी और न ही सॉर्टिडरेड (वे अद्वितीय कुंजी की आवश्यकता होती है) का उपयोग नहीं कर सकते हैं। यह आपको एक SortedList के साथ छोड़ देता है।

मुझे समझ में नहीं आता है कि आप अपने मुख्य / पहले शब्दकोश में मूल आइटम के लिंक को बनाए रखने पर जोर क्यों देते हैं।

यदि आपके संग्रह की वस्तुओं में एक अधिक जटिल संरचना (अधिक क्षेत्र) थी और आपको कुंजी के रूप में कई अलग-अलग क्षेत्रों का उपयोग करके उन्हें कुशलतापूर्वक एक्सेस / सॉर्ट करने में सक्षम होना चाहिए - आपको संभवतः एक कस्टम डेटा संरचना की आवश्यकता होगी जिसमें मुख्य भंडारण शामिल होगा O (1) सम्मिलन और निष्कासन (लिंक्डलिस्ट) और कई अनुक्रमण संरचनाओं का समर्थन करता है - शब्दकोश / SortedD शब्दकोशों / SortedLists। ये इंडेक्स आपके कॉम्प्लेक्स क्लास के एक फ़ील्ड को एक कुंजी के रूप में और एक लिंक्डइन में LinkedListNode के लिए एक पॉइंटर / संदर्भ के रूप में एक मान के रूप में उपयोग करेगा।

आपको अपने अनुक्रमणिका को मुख्य संग्रह (लिंक्डलिस्ट) के साथ सिंक में रखने के लिए सम्मिलन और निष्कासन का समन्वय करने की आवश्यकता होगी और निष्कासन मेरे विचार से बहुत महंगा होगा। यह उसी तरह है जैसे डेटाबेस अनुक्रमणिका काम करती है - वे लुकअप के लिए शानदार हैं लेकिन जब आप कई इंसेटिव और डिलीट करने की आवश्यकता होती है तो वे बोझ बन जाते हैं।

यदि आप कुछ लुक-अप हैवी प्रोसेसिंग करने जा रहे हैं, तो उपरोक्त सभी उचित है। यदि आपको केवल आवृत्ति द्वारा छांटे जाने के बाद उन्हें आउटपुट करने की आवश्यकता है तो आप (अनाम) टुपल्स की एक सूची तैयार कर सकते हैं:

var dict = new SortedDictionary<string, int>();
// ToDo: populate dict

var output = dict.OrderBy(e => e.Value).Select(e => new {frequency = e.Value, word = e.Key}).ToList();

foreach (var entry in output)
{
    Console.WriteLine("frequency:{0}, word: {1}",entry.frequency,entry.word);
}

उच्च स्तर पर, आपके पास पूरे शब्दकोश के माध्यम से चलने और प्रत्येक मूल्य को देखने के अलावा और कोई विकल्प नहीं है।

शायद इससे मदद मिलती है: http://bytes.com/forum/thread563638.html जॉन टिम्नी से कॉपी / पेस्ट करना:

Dictionary<string, string> s = new Dictionary<string, string>();
s.Add("1", "a Item");
s.Add("2", "c Item");
s.Add("3", "b Item");

List<KeyValuePair<string, string>> myList = new List<KeyValuePair<string, string>>(s);
myList.Sort(
    delegate(KeyValuePair<string, string> firstPair,
    KeyValuePair<string, string> nextPair)
    {
        return firstPair.Value.CompareTo(nextPair.Value);
    }
);

चारों ओर देख रहे हैं, और कुछ C # 3.0 सुविधाओं का उपयोग करके हम यह कर सकते हैं:

foreach (KeyValuePair<string,int> item in keywordCounts.OrderBy(key=> key.Value))
{ 
    // do something with item.Key and item.Value
}

यह सबसे साफ तरीका है जो मैंने देखा है और हैश को संभालने के रूबी तरीके के समान है।


मान लीजिए कि हमारे पास एक शब्दकोश है

   Dictionary<int, int> dict = new Dictionary<int, int>();
   dict.Add(21,1041);
   dict.Add(213, 1021);
   dict.Add(45, 1081);
   dict.Add(54, 1091);
   dict.Add(3425, 1061);
   sict.Add(768, 1011);

1) आप temporary dictionary to store values as लिए temporary dictionary to store values as उपयोग कर सकते हैं:

        Dictionary<int, int> dctTemp = new Dictionary<int, int>();

        foreach (KeyValuePair<int, int> pair in dict.OrderBy(key => key.Value))
        {
            dctTemp .Add(pair.Key, pair.Value);
        }

यह देखते हुए कि आपके पास एक शब्दकोष है जिसे आप एक लाइनर के नीचे मानों पर सीधे छाँट सकते हैं:

var x = (from c in dict orderby c.Value.Order ascending select c).ToDictionary(c => c.Key, c=>c.Value);

या मनोरंजन के लिए आप कुछ LINQ एक्सटेंशन अच्छाई का उपयोग कर सकते हैं:

var dictionary = new Dictionary<string, int> { { "c", 3 }, { "a", 1 }, { "b", 2 } };
dictionary.OrderBy(x => x.Value)
  .ForEach(x => Console.WriteLine("{0}={1}", x.Key,x.Value));

सॉर्ट किए गए डिक्शनरी को प्राप्त करने का सबसे आसान तरीका है बिल्ट इन SortedDictionary क्लास का उपयोग करना:

//Sorts sections according to the key value stored on "sections" unsorted dictionary, which is passed as a constructor argument
System.Collections.Generic.SortedDictionary<int, string> sortedSections = null;
if (sections != null)
{
    sortedSections = new SortedDictionary<int, string>(sections);
}

सॉर्ट किए गए sections में सॉर्ट किए गए संस्करण होंगे


var ordered = dict.OrderBy(x => x.Value);







dictionary