文字列キーまたはインデックスによって値を取得できる(パフォーマンスと使いやすさのための)最も理想的なデータ構造を探しています。インデックスで実際に取得できないため、辞書は機能しません。何か案は?
7 に答える
OrderedDictionaryクラスが必要です。System.Collections.Specialized 名前空間を含める必要があります。
OrderedDictionary od = new OrderedDictionary();
od.Add("abc", 1);
od.Add("def", 2);
od.Add("ghi", 3);
od.Add("jkl", 4);
// Can access via index or key value:
Console.WriteLine(od[1]);
Console.WriteLine(od["def"]);
警告の一言。は、挿入とルックアップを除くほとんどの操作でパフォーマンス特性OrderedDictionary
が非常に悪いです。値の削除と変更の両方で、リスト全体の線形検索が必要になる場合があり、実行時O(n)になります。(変更の場合、これはアクセスがインデックスまたはキーのどちらで発生したかによって異なります。)
妥当な量のデータを使用するほとんどの操作では、これは完全に受け入れられません。さらに、データ構造は要素を線形ベクトルとハッシュテーブルの両方に格納するため、メモリのオーバーヘッドが発生します。
インデックスによる取得があまり頻繁に行われない場合、SortedList
またはははるかに優れたパフォーマンス特性を備えています(インデックスによるアクセスは拡張メソッドSortedDictionary
を介して実現できます)。ElementAt
一方、インデックスによるアクセスが標準である場合は、ディクショナリデータ構造の使用をすべて停止し、値をに格納するだけList<KeyValuePair<TKey, TValue>>
です。これは、キーによるアクセスの線形検索を意味しますが、他のすべての操作は非常に安価であり、全体的なパフォーマンスは実際には打ち負かされません。
/編集:もちろん、後者は理論的な意味での辞書データ構造でもあります。適切なインターフェースを実装するクラスにカプセル化することもできます。
System.Collections.ObjectModel があります。Collection< TItem> から派生したKeyedCollection< string,TItem > 。取得は O(1)です。
class IndexableDictionary<TItem> : KeyedCollection<string, TItem>
{ Dictionary<TItem, string> keys = new Dictionary<TItem, string>();
protected override string GetKeyForItem(TItem item) { return keys[item];}
public void Add(string key, TItem item)
{ keys[item] = key;
this.Add(item);
}
}
SortedDictionary <string、TValue>またはSortedList <string、TValue>を使用することをお勧めします。どちらもO(log n)検索パフォーマンスを備えています。
違いは、MSDNライブラリから引用されているように:
SortedList <(Of <(TKey、TValue>)>)は、SortedDictionary <(Of <(TKey、TValue>)>)よりも少ないメモリを使用します。
SortedDictionary <(Of <(TKey、TValue>)>)は、ソートされていないデータの挿入および削除操作が高速です。SortedList<(Of <(TKey、TValue>)>)のO(n)とは対照的に、O(log n)です。
ソートされたデータからリストに一度にデータが入力される場合、SortedList <(Of <(TKey、TValue>)>)はSortedDictionary <(Of <(TKey、TValue>)>)よりも高速です。
私の経験では、SortedDictionaryは、ほとんどの一般的なビジネスシナリオに適しています。これは、このような構造を使用する場合、データは通常最初は並べ替えられておらず、SortedDictionaryのメモリオーバーヘッドが重要になることはめったにないためです。ただし、パフォーマンスが重要な場合は、両方を実装して測定を行うことをお勧めします。
ハッシュベースのコレクション(Dictionary、Hashtable、HashSet)は、インデックスがないために使用できません。インデックスが必要なため、ネストされたジェネリックを使用します。
List<KeyValuePair<K,V>>
もちろん、ハッシュで取得したO(1)キールックアップは失われます。
Dictionary は linq で使用できます。パフォーマンスの問題の可能性については知りませんが。Dictionary.ElementAt(インデックス);
あなたはSortedListクラスのようなものを探しています(これも一般的なバージョンです)。