辞書を値で並べ替えるには?
キーとハッシュと値で構成される辞書を、値でソートする必要があることがよくあります。例えば、単語とそれぞれの頻度のハッシュを持っていて、頻度順に並べたい。
一つの値(例えば頻度)に適したSortedList
があり、それを単語にマッピングして戻したいのです。
SortedDictionaryは、値ではなく、キーで注文します。カスタムクラス](http://www.codeproject.com/KB/recipes/lookupcollection.aspx)に頼る人もいますが、もっときれいな方法はないでしょうか?
768
18
使用する:
.NET 2.0以上をターゲットにしているので、これを簡略化してラムダ構文にすることができます(これと同等ですが、より短いです)。Visual Studio 2008 (またはそれ以上)のコンパイラを使用している場合のみ、この構文を使用することができます。
LINQを使用します。
これにより、上位10、20、10%などを選択できるという大きな柔軟性も得られます。 または、「type-ahead」にワード周波数インデックスを使用している場合は、「StartsWith」句を含めることもできます。
C#3.0の機能を使えば、このようなことも可能です:
これは私が見た中で最もクリーンな方法で、Rubyのハッシュの扱い方と似ています。
辞書を値でソートして、それ自体に保存できます(そのため、それを詳しく説明すると、値が順番に表示されます)。
もちろん、正しくないかもしれませんが、機能します。
高いところでは、ディクショナリー全体を歩いて、各バリューを見る以外の選択肢はない。
もしかしたら、これが役に立つかもしれません: http://bytes.com/forum/thread563638.html ジョン・ティムニーからのコピー・ペーストです:
とにかく辞書を並べ替えることはできません。 彼らは実際に注文されていません。 ディクショナリの保証は、キーと値のコレクションが反復可能であり、値がインデックスまたはキーで取得できることですが、特定の順序の保証はありません。 したがって、名前値のペアをリストに入れる必要があります。
辞書のエントリをソートしません。 .NETの辞書クラスはハッシュテーブルとして実装されています-このデータ構造は定義によってソートできません。
コレクションを(キーで)反復できる必要がある場合は、バイナリ検索ツリーとして実装されているSortedDictionaryを使用する必要があります。
ただし、別のフィールドでソートされるため、ソース構造は無関係です。 頻度で並べ替え、関連するフィールド(頻度)で並べ替えた新しいコレクションに入れる必要があります。 したがって、このコレクションでは、周波数はキーであり、単語は値です。 多くの単語は同じ頻度を持つことができるため(キーとして使用するため)、辞書もSortedDictionaryも使用できません(一意のキーが必要です)。 これにより、SortedListが残ります。
メイン/ファースト辞書の元のアイテムへのリンクを維持することを主張する理由がわかりません。
コレクション内のオブジェクトがより複雑な構造になっている場合。 (より多くのフィールド。) また、いくつかの異なるフィールドをキーとして使用して効率的にアクセス/ソートできるようにする必要がありました。おそらく、Oをサポートするメインストレージで構成されるカスタムデータ構造が必要になります。(1。) 挿入と削除。 (LinkedList。) およびいくつかのインデックス構造-辞書/ SortedDictionaries / SortedLists。 これらのインデックスは、複雑なクラスのフィールドの1つをキーとして使用し、LinkedListNode< YourClass>へのポインター/参照を使用します。 LinkedListで値として。
インデックスをメインコレクション(LinkedList)と同期させるには、挿入と削除を調整する必要があり、削除はかなり費用がかかると思います。 これは、データベースインデックスの動作に似ています。ルックアップには最適ですが、多くの挿入と削除を実行する必要がある場合に負担になります。
上記のすべては、ルックアップの重い処理を行う場合にのみ正当化されます。 周波数で並べ替えられたときにのみ出力する必要がある場合は、(匿名)タプルのリストを作成できます。
値をソートします。
これは、辞書で値をソートする方法を示しています。 Visual Studioでコンパイルして実行できるコンソールプログラムが表示されます。 辞書にキーを追加し、値で並べ替えます。 辞書インスタンスは、最初はまったくソートされないことに注意してください。 クエリステートメントでは、LINQ orderbyキーワードを使用します。
OrderBy句。 辞書[C#]をソートするプログラム。
出力。
または、楽しみのために、いくつかのLINQ拡張の良さを使用できます。
VB.NETを使用して「ListView」コントロールにバインドする「SortedDictionary」リストの並べ替え:
XAML:
ソートされた辞書を取得する最も簡単な方法は、組み込みの「SortedDictionary」クラスを使用することです。
sortedSections
には、sections
のソートバージョンが含まれます。「一時」リストを値でソートすることだけが必要な場合は、他の回答は適切です。 ただし、
Key
でソートされた辞書を、Value
でソートされた別の辞書と_自動同期する_にしたい場合は、[Bijection< K1、K2>
class](http:// ecsharp.net / doc / classLoyc_1_1Collections_1_1Bijection.html)。Bijection< K1、K2>
を使用すると、2つの既存の辞書でコレクションを初期化できます。そのため、そのうちの1つをソート解除し、もう1つをソートする場合は、コードなどのバイジェクションを作成できます。通常の辞書と同様に「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)
一時辞書を使用して、値を
として保存できます。実際にはC#では、辞書にはsort()メソッドがあります。 値でソートすることにもっと興味があるので。 キーを提供するまで値を取得できません。 要するに、あなたはそれらを通して反復する必要があります。 LINQの注文者を使用します。
1つのトリックを実行できます。
または。
また、どのような値を保存しているかにも依存します。 単一(文字列、intなど)または複数(リスト、配列、ユーザー定義クラスなど)ですか。 シングルの場合は、リストを作成してソートを適用できます。 ユーザー定義クラスの場合。 次に、そのクラスはIComparableを実装する必要があります。
ClassName:IComparable< ClassName>
およびcompareTo(ClassName c)
をオーバーライドします。 それらはLINQよりも速く、オブジェクト指向であるため。辞書があれば、以下の1つのライナーを使用して値で直接並べ替えることができます。
値で辞書をソートし、以下のコードを使用して結果を辞書で取得できます。