辞書を値で並べ替えるには?

キーとハッシュと値で構成される辞書を、値でソートする必要があることがよくあります。例えば、単語とそれぞれの頻度のハッシュを持っていて、頻度順に並べたい。

一つの値(例えば頻度)に適したSortedListがあり、それを単語にマッピングして戻したいのです。

SortedDictionaryは、値ではなく、キーで注文します。カスタムクラス](http://www.codeproject.com/KB/recipes/lookupcollection.aspx)に頼る人もいますが、もっときれいな方法はないでしょうか

質問へのコメント (1)
ソリューション

使用する:

using System.Linq.Enumerable;
...
List myList = aDictionary.ToList();

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

.NET 2.0以上をターゲットにしているので、これを簡略化してラムダ構文にすることができます(これと同等ですが、より短いです)。Visual Studio 2008 (またはそれ以上)のコンパイラを使用している場合のみ、この構文を使用することができます。

var myList = aDictionary.ToList();

myList.Sort((pair1,pair2) => pair1.Value.CompareTo(pair2.Value));
解説 (11)

LINQを使用します。

Dictionary myDict = new Dictionary();
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」句を含めることもできます。

解説 (12)
var ordered = dict.OrderBy(x => x.Value);
解説 (9)

C#3.0の機能を使えば、このようなことも可能です:

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

これは私が見た中で最もクリーンな方法で、Rubyのハッシュの扱い方と似ています。

解説 (5)

辞書を値でソートして、それ自体に保存できます(そのため、それを詳しく説明すると、値が順番に表示されます)。

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

もちろん、正しくないかもしれませんが、機能します。

解説 (8)

高いところでは、ディクショナリー全体を歩いて、各バリューを見る以外の選択肢はない。

もしかしたら、これが役に立つかもしれません: http://bytes.com/forum/thread563638.html ジョン・ティムニーからのコピー・ペーストです:

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

List myList = new List (s);
myList.Sort(
    delegate(KeyValuePair firstPair、
    KeyValuePair nextPair) です。
    {
        return firstPair.Value.CompareTo(nextPair.Value);
    }
);
解説 (2)

とにかく辞書を並べ替えることはできません。 彼らは実際に注文されていません。 ディクショナリの保証は、キーと値のコレクションが反復可能であり、値がインデックスまたはキーで取得できることですが、特定の順序の保証はありません。 したがって、名前値のペアをリストに入れる必要があります。

解説 (7)

辞書のエントリをソートしません。 .NETの辞書クラスはハッシュテーブルとして実装されています-このデータ構造は定義によってソートできません。

コレクションを(キーで)反復できる必要がある場合は、バイナリ検索ツリーとして実装されているSortedDictionaryを使用する必要があります。

ただし、別のフィールドでソートされるため、ソース構造は無関係です。 頻度で並べ替え、関連するフィールド(頻度)で並べ替えた新しいコレクションに入れる必要があります。 したがって、このコレクションでは、周波数はキーであり、単語は値です。 多くの単語は同じ頻度を持つことができるため(キーとして使用するため)、辞書もSortedDictionaryも使用できません(一意のキーが必要です)。 これにより、SortedListが残ります。

メイン/ファースト辞書の元のアイテムへのリンクを維持することを主張する理由がわかりません。

コレクション内のオブジェクトがより複雑な構造になっている場合。 (より多くのフィールド。) また、いくつかの異なるフィールドをキーとして使用して効率的にアクセス/ソートできるようにする必要がありました。おそらく、Oをサポートするメインストレージで構成されるカスタムデータ構造が必要になります。(1。) 挿入と削除。 (LinkedList。) およびいくつかのインデックス構造-辞書/ SortedDictionaries / SortedLists。 これらのインデックスは、複雑なクラスのフィールドの1つをキーとして使用し、LinkedListNode< YourClass>へのポインター/参照を使用します。 LinkedListで値として。

インデックスをメインコレクション(LinkedList)と同期させるには、挿入と削除を調整する必要があり、削除はかなり費用がかかると思います。 これは、データベースインデックスの動作に似ています。ルックアップには最適ですが、多くの挿入と削除を実行する必要がある場合に負担になります。

上記のすべては、ルックアップの重い処理を行う場合にのみ正当化されます。 周波数で並べ替えられたときにのみ出力する必要がある場合は、(匿名)タプルのリストを作成できます。

var dict = new SortedDictionary();
// 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);
}
解説 (0)
Dictionary dic= new Dictionary();
var ordered = dic.OrderBy(x => x.Value);
return ordered.ToDictionary(t => t.Key, t => t.Value);
解説 (1)

値をソートします。

これは、辞書で値をソートする方法を示しています。 Visual Studioでコンパイルして実行できるコンソールプログラムが表示されます。 辞書にキーを追加し、値で並べ替えます。 辞書インスタンスは、最初はまったくソートされないことに注意してください。 クエリステートメントでは、LINQ orderbyキーワードを使用します。

OrderBy句。 辞書[C#]をソートするプログラム。

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

class Program
{
    static void Main()
    {
        // Example dictionary.
        var dictionary = new Dictionary(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 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;
    }
}

出力。

dog: 0
cat: 1
programmer: 2
eel: 3
mouse: 5
解説 (0)

または、楽しみのために、いくつかのLINQ拡張の良さを使用できます。

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

VB.NETを使用して「ListView」コントロールにバインドする「SortedDictionary」リストの並べ替え:

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:








解説 (0)

ソートされた辞書を取得する最も簡単な方法は、組み込みの「SortedDictionary」クラスを使用することです。

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

sortedSectionsには、 sectionsのソートバージョンが含まれます。

解説 (3)

「一時」リストを値でソートすることだけが必要な場合は、他の回答は適切です。 ただし、 Keyでソートされた辞書を、 Valueでソートされた別の辞書と_自動同期する_にしたい場合は、[Bijection< K1、K2>class](http:// ecsharp.net / doc / classLoyc_1_1Collections_1_1Bijection.html)。

Bijection< K1、K2>を使用すると、2つの既存の辞書でコレクションを初期化できます。そのため、そのうちの1つをソート解除し、もう1つをソートする場合は、コードなどのバイジェクションを作成できます。

var dict = new Bijection(new Dictionary(), 
                               new SortedDictionary());

通常の辞書と同様に「dict」を使用して(「IDictionary< K、V>」を実装します)、次に「dict.Inverse」を呼び出して、「Value」でソートされた「inverse」辞書を取得できます。

Bijection< K1、K2>Loyc.Collections.dllの一部ですが、必要に応じて、[ソースコード](https://github.com/qwertie/Loyc/blob/master/Core/Loyc.Collections/Other.

:同じ値の複数のキーがある場合、「Bijection」は使用できませんが、通常の「Dictionary< Key、Value>」と[BMultiMap< Value、Key>]を手動で同期できます。 '](http://loyc.net/doc/code/classLoyc_1_1.

解説 (1)

辞書があるとします。

   Dictionary dict = new Dictionary();
   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) 一時辞書を使用して、値をとして保存できます。

        Dictionary dctTemp = new Dictionary();

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

実際にはC#では、辞書にはsort()メソッドがあります。 値でソートすることにもっと興味があるので。 キーを提供するまで値を取得できません。 要するに、あなたはそれらを通して反復する必要があります。 LINQの注文者を使用します。

var items = new Dictionary();
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
}

1つのトリックを実行できます。

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

または。

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

また、どのような値を保存しているかにも依存します。 単一(文字列、intなど)または複数(リスト、配列、ユーザー定義クラスなど)ですか。 シングルの場合は、リストを作成してソートを適用できます。 ユーザー定義クラスの場合。 次に、そのクラスはIComparableを実装する必要があります。 ClassName:IComparable< ClassName>および compareTo(ClassName c)をオーバーライドします。 それらはLINQよりも速く、オブジェクト指向であるため。

解説 (0)

辞書があれば、以下の1つのライナーを使用して値で直接並べ替えることができます。

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

値で辞書をソートし、以下のコードを使用して結果を辞書で取得できます。

Dictionary  ShareUserNewCopy = 
       ShareUserCopy.OrderBy(x => x.Value).ToDictionary(pair => pair.Key,
                                                        pair => pair.Value);                                          
解説 (2)