[c#] C#での多次元キーによるハッシュテーブル


6 Answers

何らかの種類のタプル構造を持つ正規の辞書をキーとして使うのはどうですか?

public class TwoKeyDictionary<K1,K2,V>
{
    private readonly Dictionary<Pair<K1,K2>, V> _dict;

    public V this[K1 k1, K2 k2]
    {
        get { return _dict[new Pair(k1,k2)]; }
    }

    private struct Pair
    {
        public K1 First;
        public K2 Second;

        public override Int32 GetHashCode()
        {
            return First.GetHashCode() ^ Second.GetHashCode();
        }

        // ... Equals, ctor, etc...
    }
}
Question

私は基本的には、C#で2次元の型付きキーを使用してハッシュテーブル値にアクセスする方法を探しています。

最終的に私はこのようなことをすることができるだろう

HashTable[1][false] = 5;
int a = HashTable[1][false];
//a = 5

これは私が試みてきたことです...働いていません

Hashtable test = new Hashtable();
test.Add(new Dictionary<int, bool>() { { 1, true } }, 555);
Dictionary<int, bool> temp = new Dictionary<int, bool>() {{1, true}};
string testz = test[temp].ToString(); 



2次元キーを別のtypeラップし、そのタイプをキーとして使用します。 GetHashCode() Equals()メソッドとEquals()メソッドをオーバーライドすることも検討してください。 HashTable代わりにDictionary<>を使用することをお勧めします。




boolとintの各プロパティを公開する小さなカスタムクラスを作成し、そのGetHashCodeメソッドとEqualsメソッドをオーバーライドし、これをキーとして使用することをお勧めします。




私はこれがあなたが探しているものに近いかもしれないと思う...

var data = new Dictionary<int, Dictionary<bool, int>>();



私はキーのペアのためのクラスを作成することを避けることができますjachymkoのソリューションにわずかなバリエーションをお勧めします。 代わりに、辞書のプライベート辞書を次のようにラップします。

public class MultiDictionary<K1, K2, V>
{
    private Dictionary<K1, Dictionary<K2, V>> dict = 
        new Dictionary<K1, Dictionary<K2, V>>();

    public V this[K1 key1, K2 key2]
    {
        get
        {
            return dict[key1][key2];
        }

        set
        {
            if (!dict.ContainsKey(key1))
            {
                dict[key1] = new Dictionary<K2, V>();
            }
            dict[key1][key2] = value;
        }
    }
}



素早く汚れた方法は、2つの情報から複合キーを作成することです。

IDictionary<string, int> values = new Dictionary<string, int>();
int i = ...;
bool b = ...;
string key = string.Concat(i, '\0', b);
values[key] = 555;

これを少しうまくカプセル化するには、辞書をラップすることができます:

public class MyDict
{
    private readonly IDictionary<string, int> values = new Dictionary<string, int>();

    public int this[int i, bool b]
    {
        get
        {
            string key = BuildKey(i, b);
            return values[key];
        }

        set
        {
            string key = BuildKey(i, b);
            values[key] = value;
        }
    }

    private static string BuildKey(int i, bool b)
    {
        return string.Concat(i, '\0', b);
    }
}

これをより堅牢にするには、コンポジットキーをタイプ(例えば、2つのフィールドを含むクラス)としてカプセル化し、Equals()メソッドとGetHashCode()メソッドを正しくオーバーライドするようにします。




つまり、あなたのメインディクショナリはDictionary<int, Dictionary<bool, my_return_type>>型のハッシュテーブルを「ダブルネスト」することができます。

これにより、最初のコードスニペットで二重括弧表記を使用できるという目標が達成されます。

もちろん、管理面は少し面倒です。 エントリを追加するたびに、メイン辞書にプライマリキーの辞書が含まれているかどうかをテストし、そうでなければ新しい辞書を追加してから、セカンダリのキーと値を内部ディクショナリに追加する必要があります。




Related