キーと値のペアのデータ構造の最適な実装は?
-
08-06-2019 - |
質問
最近、C# を少しいじっていますが、すべてのジェネリック コレクションに少し混乱しています。ツリーの先頭がキーと値のペアであり、その下にキーと値のペアのオプションのリストが 1 つある (ただし、これら以上のレベルは存在しない) データ構造を表現したいとします。これは適切でしょうか?
public class TokenTree
{
public TokenTree()
{
/* I must admit to not fully understanding this,
* I got it from msdn. As far as I can tell, IDictionary is an
* interface, and Dictionary is the default implementation of
* that interface, right?
*/
SubPairs = new Dictionary<string, string>();
}
public string Key;
public string Value;
public IDictionary<string, string> SubPairs;
}
これは実際にはデータを渡すための単純なシャントにすぎません。
解決
KeyValuePair という実際のデータ型があります。次のように使用します。
KeyValuePair<string, string> myKeyValuePair = new KeyValuePair<string,string>("defaultkey", "defaultvalue");
他のヒント
考えられることの 1 つは、Dictionary オブジェクトをそのまま使用し、独自の変更を加えて拡張することです。
public class TokenTree : Dictionary<string, string>
{
public IDictionary<string, string> SubPairs;
}
これにより、キーに対して IDictionary のルール (キーの一意性など) を強制する必要がなくなるという利点が得られます。
そして、はい、コンストラクターの概念を正しく理解しました:)
(あなたの質問の文字通りの実装として)あなたが望んでいることは次のとおりだと思います:
public class TokenTree
{
public TokenTree()
{
tree = new Dictionary<string, IDictionary<string,string>>();
}
IDictionary<string, IDictionary<string, string>> tree;
}
実際、質問の中で Key-Value の「リスト」と述べたので、内部のキーと値を交換した方がよいかもしれません。 IDictionary
とともに:
IList<KeyValuePair<string, string>>
KeyValuePair 組み込み型があります。実際、これは IDictionary を反復処理するときにアクセスできるようにするものです。
また、この構造はほとんどツリーではないため、より代表的な名前を見つけることは良い練習になるかもしれません。
これに 1 つだけ付け加えておきます (ただし、あなたの質問はすでに他の人から回答されていると思います)。拡張性を考慮して (いつかはそうなることは誰もが知っているので)、以下をチェックしてみるとよいでしょう。 複合パターン これは、「木のような構造」を扱うのに最適です。
先ほども言いましたが、サブレベルが 1 つしか期待されていないことはわかっていますが、これは後で拡張する必要がある場合に非常に役立つ可能性があります ^_^
@ジェイ・ムーニー:.NET の汎用 Dictionary クラスは、実際には固定型のみを備えたハッシュ テーブルです。
あなたが示したコードは、両方のコード部分が両方のタイプに使用できるため、Dictionary の代わりに Hashtable を使用するように説得する必要はありません。
ハッシュテーブルの場合:
foreach(object key in h.keys)
{
string keyAsString = key.ToString(); // btw, this is unnecessary
string valAsString = h[key].ToString();
System.Diagnostics.Debug.WriteLine(keyAsString + " " + valAsString);
}
辞書の場合:
foreach(string key in d.keys)
{
string valAsString = d[key].ToString();
System.Diagnostics.Debug.WriteLine(key + " " + valAsString);
}
もう一方の KeyValuePair についても同様で、Hashtable には非ジェネリック バージョンを使用し、Dictionary にはジェネリック バージョンを使用します。
どちらの方法でも同じように簡単ですが、Hashtable はキーと値の両方に Object を使用します。つまり、すべての値の型をボックス化することになり、型安全性がありません。Dictionary はジェネリック型を使用するため、より優れています。
辞書クラス まさにあなたが望むものです、正しいです。
フィールドを IDictionary ではなく Dictionary として直接宣言することもできますが、それはあなた次第です。
次のようなものを使用します。
class Tree < T > : Dictionary < T, IList< Tree < T > > >
{
}
醜いですが、あなたが望むものを与えると思います。KeyValuePair が封印されているのが残念です。