c# - länge - title tag definition




Wie sortieren Sie ein Wörterbuch nach Wert? (12)

Ich muss oft ein Wörterbuch, bestehend aus Schlüsseln und Werten, nach Wert sortieren. Zum Beispiel habe ich einen Hash von Wörtern und entsprechenden Häufigkeiten, die ich nach Häufigkeit sortieren möchte.

Es gibt eine SortedList die für einen einzelnen Wert (zB Frequenz) gut ist, dass ich es zurück zum Wort SortedList möchte.

SortedDictionary Bestellungen nach Schlüssel, nicht nach Wert. Einige greifen auf eine benutzerdefinierte Klasse zurück , aber gibt es einen saubereren Weg?


Angenommen, wir haben ein Wörterbuch als

   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) Sie können das 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);
        }

Auf einer höheren Ebene haben Sie keine andere Wahl, als das gesamte Wörterbuch durchzugehen und jeden Wert zu betrachten.

Vielleicht hilft das: http://bytes.com/forum/thread563638.html Kopieren / Einfügen von John Timney:

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);
    }
);

Der einfachste Weg, ein sortiertes Dictionary zu erhalten, ist die Verwendung der eingebauten SortedDictionary Klasse:

//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);
}

sortedSections enthält die sortierte Version der sections


Die anderen Antworten sind gut, wenn Sie alles, was Sie wollen, eine "temporäre" Liste nach Wert sortiert haben. Wenn Sie jedoch ein Wörterbuch nach Key sortiert haben möchten, das automatisch mit einem anderen nach Value sortierten Wörterbuch synchronisiert wird, können Sie die Klasse Bijection<K1, K2> .

Bijection<K1, K2> ermöglicht es Ihnen, die Sammlung mit zwei vorhandenen Wörterbüchern zu initialisieren. Wenn Sie also möchten, dass eine davon unsortiert ist und Sie möchten, dass die andere sortiert wird, können Sie Ihre Bijektion mit Code wie

var dict = new Bijection<Key, Value>(new Dictionary<Key,Value>(), 
                               new SortedDictionary<Value,Key>());

Sie können dict wie jedes normale Wörterbuch verwenden (es implementiert IDictionary<> ) und dann dict.Inverse , um das "inverse" Wörterbuch zu erhalten, das nach Value sortiert ist.

Bijection<K1, K2> ist Teil von Loyc.Collections.dll , aber wenn Sie möchten, können Sie den Quellcode einfach in Ihr eigenes Projekt kopieren.

Hinweis : Bijection mehrere Schlüssel mit demselben Wert vorhanden sind, können Sie keine Bijection , aber Sie können manuell zwischen einem gewöhnlichen Dictionary<Key,Value> und einem BMultiMap<Value,Key> synchronisieren.


Sie können das Wörterbuch nach Wert sortieren und das Ergebnis im Wörterbuch mit dem folgenden Code abrufen:

Dictionary <<string, string>> ShareUserNewCopy = 
       ShareUserCopy.OrderBy(x => x.Value).ToDictionary(pair => pair.Key,
                                                        pair => pair.Value);                                          

Sie können ein Dictionary nach Wert sortieren und es in sich selbst zurückspeichern (so dass, wenn Sie darüber nachdenken, die Werte in der richtigen Reihenfolge ausgegeben werden):

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

Sicher, es mag nicht korrekt sein, aber es funktioniert.


Sie sortieren keine Einträge im Dictionary. Die Dictionary-Klasse in .NET ist als Hashtable implementiert - diese Datenstruktur ist per Definition nicht sortierbar.

Wenn Sie in der Lage sein müssen, über Ihre Sammlung zu iterieren (nach Schlüssel), müssen Sie SortedDictionary verwenden, das als Binärsuchbaum implementiert ist.

In Ihrem Fall ist die Quellstruktur jedoch irrelevant, da sie nach einem anderen Feld sortiert ist. Sie müssten es immer noch nach Häufigkeit sortieren und in einer neuen Sammlung nach dem entsprechenden Feld (Häufigkeit) sortieren. In dieser Sammlung sind also die Frequenzen Schlüssel und Wörter sind Werte. Da viele Wörter dieselbe Häufigkeit haben können (und Sie sie als Schlüssel verwenden), können Sie weder Dictionary noch SortedDictionary verwenden (sie benötigen eindeutige Schlüssel). Dies hinterlässt eine SortedList.

Ich verstehe nicht, warum Sie darauf bestehen, einen Link zum Originalartikel in Ihrem Haupt- / ersten Wörterbuch zu führen.

Wenn die Objekte in Ihrer Sammlung eine komplexere Struktur (mehr Felder) hätten und Sie in der Lage wären, effizient auf mehrere verschiedene Felder als Schlüssel zuzugreifen / zu sortieren, würden Sie wahrscheinlich eine benutzerdefinierte Datenstruktur benötigen, die aus dem Hauptspeicher bestehen würde unterstützt O (1) Einfügen und Entfernen (LinkedList) und mehrere Indexstrukturen - Wörterbücher / SortedDictionaries / SortedLists. Diese Indizes würden eines der Felder aus Ihrer komplexen Klasse als Schlüssel und einen Zeiger / Verweis auf den LinkedListNode in der LinkedList als Wert verwenden.

Sie müssten Einfügungen und Entfernungen koordinieren, um Ihre Indizes mit der Hauptsammlung (LinkedList) synchron zu halten, und Entfernungen wären ziemlich teuer, denke ich. Dies ist vergleichbar mit der Funktionsweise von Datenbankindizes - sie sind fantastisch für Nachschlagevorgänge, sie werden jedoch zu einer Last, wenn Sie viele Einfügungen und Löschungen durchführen müssen.

All das ist nur dann gerechtfertigt, wenn Sie eine Nachbearbeitung durchführen wollen. Wenn Sie sie nur einmal nach Häufigkeit sortiert ausgeben müssen, könnten Sie einfach eine Liste von (anonymen) Tupeln erstellen:

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);
}

Sortieren einer SortedDictionary Liste zum Binden in ein ListView Steuerelement mithilfe von VB.NET:

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>

Wenn Sie ein Wörterbuch haben, können Sie sie direkt auf Werte unter einem Liner sortieren:

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

Wenn Sie sich umsehen und einige C # 3.0-Funktionen verwenden, können wir Folgendes tun:

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

Dies ist die sauberste Art und Weise, die ich gesehen habe, und ähnelt der Ruby-Art, mit Hashes umzugehen.


Dictionary<string, string> dic= new Dictionary<string, string>();
var ordered = dic.OrderBy(x => x.Value);
return ordered.ToDictionary(t => t.Key, t => t.Value);

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






dictionary