Wie sortieren Sie einen Wörterbuch von Wert?

stimmen
671

Ich muß oft ein Wörterbuch sortieren, bestehend aus Schlüsseln und Werten, von Wert. Zum Beispiel habe ich einen Hash von Wörtern und entsprechenden Frequenzen, die ich durch Frequenz bestellen möchten.

Es ist ein , SortedListdie für einen einzelnen Wert gut ist (sagen Frequenz), dass ich es wieder auf das Wort zuordnen möchten.

SortedDictionary Bestellungen per Schlüssel, nicht Wert. Einiger Resort zu einer benutzerdefinierten Klasse , aber gibt es einen sauberen Weg?

Veröffentlicht am 02/08/2008 um 01:40
quelle vom benutzer
In anderen Sprachen...                            


18 antworten

stimmen
473

Verwenden Sie 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;

Dies würde auch eine große Flexibilität bei , dass Sie die Top-10 wählen kann, 20 10%, etc. Oder wenn Sie Ihren Worthäufigkeitsindex für verwenden type-ahead, können Sie auch gehören StartsWithKlausel als auch.

Beantwortet am 04/08/2008 um 16:22
quelle vom benutzer

stimmen
459

Benutzen:

using System.Linq.Enumerable;
...
List<KeyValuePair<string, string>> myList = aDictionary.ToList();

myList.Sort(
    delegate(KeyValuePair<string, string> pair1,
    KeyValuePair<string, string> pair2)
    {
        return pair1.Value.CompareTo(pair2.Value);
    }
);

Da Sie .NET 2.0 oder höher Targeting sind, können Sie dies in Lambda-Syntax vereinfachen - es ist gleichwertig, aber kürzer. Wenn Sie .NET 2.0-Targeting können Sie nur diese Syntax verwenden, wenn Sie den Compiler von Visual Studio 2008 (oder höher) verwenden.

var myList = aDictionary.ToList();

myList.Sort((pair1,pair2) => pair1.Value.CompareTo(pair2.Value));
Beantwortet am 02/08/2008 um 02:15
quelle vom benutzer

stimmen
179
var ordered = dict.OrderBy(x => x.Value);
Beantwortet am 11/11/2010 um 18:16
quelle vom benutzer

stimmen
148

Suchen Sie sich um, und einige C # 3.0-Features verwenden wir dies tun können:

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

Dies ist der sauberste Weg, den ich gesehen habe und ist ähnlich der Ruby-Weg-Hashes der Handhabung.

Beantwortet am 02/08/2008 um 01:43
quelle vom benutzer

stimmen
140

Sie können ein Wörterbuch nach Wert sortieren und speichern Sie es auf sich selbst zurück (so dass, wenn Sie es foreach über die Werte, um herauskommen):

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

Sicher, es kann nicht richtig sein, aber es funktioniert.

Beantwortet am 22/06/2011 um 11:26
quelle vom benutzer

stimmen
56

Auf einem hohen Niveau, haben Sie keine andere Wahl, dann durch das ganze Wörterbuch zu gehen und bei jedem Wert suchen.

Vielleicht hilft: 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);
    }
);
Beantwortet am 02/08/2008 um 01:47
quelle vom benutzer

stimmen
22

Sie würden sowieso nie ein Wörterbuch sortieren können. Sie sind nicht wirklich bestellt. Die Garantien für einen Wörterbuch sind, dass die Schlüssel und Wert Sammlungen sind iterable und Werte können durch Index oder Schlüssel abgerufen werden, aber hier sind keine Garantie für eine Bestellung. Daher müssten Sie den Namen Wertepaar in eine Liste erhalten.

Beantwortet am 19/12/2008 um 23:47
quelle vom benutzer

stimmen
16

Sie sortieren keine Einträge im Wörterbuch. Dictionary-Klasse in .NET ist als Hash-Tabelle implementiert - diese Datenstruktur per Definition nicht sortierbar ist.

Wenn Sie in der Lage sein müssen, über Ihre Sammlung iterieren (mit Schlüssel) - müssen Sie SortedDictionary verwenden, die als binärer Suchbaum implementiert ist.

In Ihrem Fall ist jedoch die Quellstruktur irrelevant, weil es von einem anderen Feld sortiert ist. Sie würden nach wie vor durch Frequenz sortieren müssen und es in einer neuen Kollektion von dem betreffenden Bereich (Frequenz) sortiert setzen. So in dieser Sammlung die Frequenzen sind Tasten und Worte sind Werte. Da viele Wörter die gleiche Frequenz haben kann (und Sie werden es als Schlüssel verwenden) können Sie weder Wörterbuch noch SortedDictionary verwenden (sie benötigen eindeutige Schlüssel). Dies lässt Sie mit einem SortedList.

Ich verstehe nicht, warum Sie darauf bestehen, auf einen Link zu dem ursprünglichen Artikel in Ihrem Haupt / ersten Wörterbuch beibehalten wird.

Wenn die Objekte in Ihrer Sammlung hatten eine komplexere Struktur (mehr Felder), und Sie müssen in der Lage sein, um effizient Zugang / sortiert sie mehr verschiedenen Felder als Schlüssel verwenden - würden Sie wahrscheinlich eine benutzerdefinierte Datenstruktur benötigen, die aus dem Hauptspeicher bestehen würden, dass unterstützt O (1) Einführen und Entfernen (VerketteteListe) und mehrere Indizierungsstrukturen - Wörterbücher / SortedDictionaries / SortedLists. Diese Indizes würde eines der Felder aus dem komplexen Klasse als Schlüssel verwenden und einen Zeiger / Verweis auf die LinkedListNode in dem LinkedList als Wert.

Sie müßten Einfügungen und Löschungen koordinieren Ihre Indizes synchron mit der Haupt-Sammlung zu halten (LinkedList) und den Abbau wäre ziemlich teuer sein, würde ich denken. Dies ist ähnlich wie Datenbankindizes arbeiten - sie sind fantastisch für Lookups aber sie werden zu einer Belastung, wenn Sie viele insetions und Löschungen durchführen müssen.

Alle der oben genannten ist nur dann gerechtfertigt, wenn Sie einige Nachschau schwere Verarbeitung tun werden. Wenn Sie nur ausgeben müssen sie einmal durch Häufigkeit sortiert, dann können Sie nur eine Liste von (anonymen) Tupel erzeugen:

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);
}
Beantwortet am 13/12/2012 um 07:19
quelle vom benutzer

stimmen
12
Dictionary<string, string> dic= new Dictionary<string, string>();
var ordered = dic.OrderBy(x => x.Value);
return ordered.ToDictionary(t => t.Key, t => t.Value);
Beantwortet am 20/07/2015 um 11:01
quelle vom benutzer

stimmen
10

Sortieren Werte

Diese zeigen, wie die Werte in einem Wörterbuch zu sortieren. Wir sehen ein Konsolenprogramm Sie in Visual Studio und führen Sie zusammenstellen können. Es fügt Schlüssel zu einem Wörterbuch und sortiert sie dann durch ihre Werte. Denken Sie daran, dass Wörterbuch Instanzen zunächst nicht in irgendeiner Weise sortiert. Wir verwenden die LINQ orderby Schlüsselwort in einer Abfrageanweisung.

OrderBy-Klausel Programm, das Wörterbuch [C #] sortiert

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        // Example dictionary.
        var dictionary = new Dictionary<string, int>(5);
        dictionary.Add("cat", 1);
        dictionary.Add("dog", 0);
        dictionary.Add("mouse", 5);
        dictionary.Add("eel", 3);
        dictionary.Add("programmer", 2);

        // Order by values.
        // ... Use LINQ to specify sorting by value.
        var items = from pair in dictionary
                orderby pair.Value ascending
                select pair;

        // Display results.
        foreach (KeyValuePair<string, int> pair in items)
        {
            Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
        }

        // Reverse sort.
        // ... Can be looped over in the same way as above.
        items = from pair in dictionary
        orderby pair.Value descending
        select pair;
    }
}

Ausgabe

dog: 0
cat: 1
programmer: 2
eel: 3
mouse: 5
Beantwortet am 20/07/2012 um 10:49
quelle vom benutzer

stimmen
10

Oder für Spaß könnte Sie einige LINQ-Erweiterung Güte verwenden:

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));
Beantwortet am 30/06/2010 um 12:12
quelle vom benutzer

stimmen
9

Eine SortedDictionarySortierliste in eine binden ListViewKontrolle VB.NET mit:

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>
Beantwortet am 23/04/2010 um 10:36
quelle vom benutzer

stimmen
5

Die anderen Antworten sind gut, wenn Sie alles , was Sie wollen , ist eine „temporäre“ Liste nach Wert sortiert haben. Wenn Sie jedoch ein Wörterbuch von sortiert haben wollen , Keydass synchronisiert sich automatisch mit einem anderen Wörterbuch , das von sortiert ist Value, können Sie die verwenden könnte Bijection<K1, K2>Klasse .

Bijection<K1, K2> können Sie die Sammlung mit zwei vorhandenen Wörterbücher initialisieren, wenn Sie also eine von ihnen wollen unsortiert sein, und Sie die andere sortiert werden möchten, können Sie Ihre Bijektion mit Code erstellen können wie

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

Sie können verwendet werden dictwie ein normales Wörterbuch (es implementiert IDictionary<>), und rufen Sie dann dict.Inversedie „inverse“ Wörterbuch zu erhalten , die durch sortiertValue .

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

Hinweis : Falls es mehrere Schlüssel mit dem gleichen Wert, können Sie nicht verwenden Bijection, aber man konnte manuell synchronisieren zwischen einem gewöhnlichen Dictionary<Key,Value>und einemBMultiMap<Value,Key> .

Beantwortet am 26/02/2016 um 07:15
quelle vom benutzer

stimmen
5

Der einfachste Weg , eine sortierte Wörterbuch zu erhalten , ist die eingebaute verwendet SortedDictionaryKlasse:

//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 Wille enthält die sortierte Version sections

Beantwortet am 02/04/2010 um 23:36
quelle vom benutzer

stimmen
4

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 verwenden können 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);
        }
Beantwortet am 02/02/2015 um 10:46
quelle vom benutzer

stimmen
0

Eigentlich in C #, Wörterbücher dint haben sort () Methoden, wie Sie mehr daran interessiert, sortieren nach Werten sind, man kann Werte erhalten, bis Sie sie Schlüssel liefern, kurz gesagt, müssen Sie sie zu durchlaufen, mit LINQ Order By,

var items = new Dictionary<string, int>();
items.Add("cat", 0);
items.Add("dog", 20);
items.Add("bear", 100);
items.Add("lion", 50);

// Call OrderBy method here on each item and provide them the ids.
foreach (var item in items.OrderBy(k => k.Key))
{
    Console.WriteLine(item);// items are in sorted order
}

Sie können einen Trick,

var sortedDictByOrder = items.OrderBy(v => v.Value);

oder

var sortedKeys = from pair in dictName
            orderby pair.Value ascending
            select pair;

seine auch davon abhängen , welche Art von Werten , die Sie speichern,
ist es einfach (wie String, int) oder mehr (wie List, Array, benutzerdefinierte Klasse),
wenn einzelne Sie die Liste dann gilt es Art zu machen.
wenn Benutzerklasse definiert, dann muss diese Klasse implementieren IComparable,
ClassName: IComparable<ClassName>und außer Kraft setzen , compareTo(ClassName c) da sie schneller als LINQ sind, und objektorientiert.

Beantwortet am 26/02/2019 um 12:39
quelle vom benutzer

stimmen
-2

Gegeben Sie ein Wörterbuch haben, können Sie sie direkt auf Werte sortieren unten Motto mit:

var x = (from c in dict orderby c.Value.Order ascending select c).ToDictionary(c => c.Key, c=>c.Value);
Beantwortet am 31/05/2014 um 23:30
quelle vom benutzer

stimmen
-2

Sie können die Wörterbuch nach Wert sortiert werden und das Ergebnis im Wörterbuch erhalten den Code unter Verwendung von:

Dictionary <<string, string>> ShareUserNewCopy = 
       ShareUserCopy.OrderBy(x => x.Value).ToDictionary(pair => pair.Key,
                                                        pair => pair.Value);                                          
Beantwortet am 24/07/2012 um 13:24
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more