C#中带有多维键的哈希表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/689940/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hashtable with MultiDimensional Key in C#
提问by Scott Schulthess
I'm basically looking for a way to access a hashtable value using a two-dimensional typed key in c#.
我基本上是在寻找一种在 c# 中使用二维类型键访问哈希表值的方法。
Eventually I would be able to do something like this
最终我将能够做这样的事情
HashTable[1][false] = 5;
int a = HashTable[1][false];
//a = 5
This is what I've been trying...hasn't worked
这是我一直在尝试的……没有奏效
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();
采纳答案by JaredPar
I think a better approach is to encapsulate the many fields of your multi-dimensional key into a class / struct. For example
我认为更好的方法是将您的多维键的许多字段封装到一个类/结构中。例如
struct Key {
public readonly int Dimension1;
public readonly bool Dimension2;
public Key(int p1, bool p2) {
Dimension1 = p1;
Dimension2 = p2;
}
// Equals and GetHashCode ommitted
}
Now you can create and use a normal HashTable and use this wrapper as a Key.
现在您可以创建和使用普通的 HashTable 并将此包装器用作键。
回答by Jason Punyon
I think this might be closer to what you're looking for...
我认为这可能更接近你正在寻找的......
var data = new Dictionary<int, Dictionary<bool, int>>();
回答by David M
I would suggest that you create a small custom class exposing the bool and int properties, and override its GetHashCode and Equals methods, then use this as the key.
我建议您创建一个公开 bool 和 int 属性的小型自定义类,并覆盖其 GetHashCode 和 Equals 方法,然后将其用作键。
回答by Mike
You might be able to "double-nest" your hashtables - in other words, your main Dictionary is of type Dictionary<int, Dictionary<bool, my_return_type>>
.
您也许可以“双重嵌套”您的哈希表 - 换句话说,您的主 Dictionary 的类型为Dictionary<int, Dictionary<bool, my_return_type>>
。
That accomplishes your goal of being able to use the double bracket notation in your first code snippet.
这实现了您能够在第一个代码片段中使用双括号表示法的目标。
Of course, the management side is a little trickier. Every time you add an entry, you need to test if the main dictionary contains a dictionary for the primary key, and add a new dictionary if not, then add the secondary key and value to the inner Dictionary.
当然,管理方面有点棘手。每次添加条目时,需要测试主字典是否包含主键的字典,如果没有则添加新字典,然后将辅助键和值添加到内部字典中。
回答by JaredPar
How about using a regular Dictionary with some kind of Tuple structure as a key?
如何使用具有某种元组结构的常规字典作为键?
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...
}
}
回答by Andrew Hare
Could you use a Dictionary<KeyValuePair<int,bool>,int>
?
你能用Dictionary<KeyValuePair<int,bool>,int>
吗?
回答by bruno conde
Wrap your two-dimensional key in a separate type
and use that type as a key. Also consider overriding GetHashCode()
and Equals()
methods. Preferably use Dictionary<>
instead of HashTable
since apparently you can use that.
将您的二维密钥单独包装起来,type
并将该类型用作密钥。还要考虑覆盖GetHashCode()
和Equals()
方法。最好使用Dictionary<>
而不是HashTable
因为显然你可以使用它。
回答by Paul Ruane
A quick and dirty way would be to create a composite key from the two pieces of information, e.g.
一种快速而肮脏的方法是从两条信息中创建一个复合键,例如
IDictionary<string, int> values = new Dictionary<string, int>();
int i = ...;
bool b = ...;
string key = string.Concat(i, '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, 'public class KeyPair<Tkey1, Tkey2>
{
public KeyPair(Tkey1 key1, Tkey2 key2)
{
Key1 = key1;
Key2 = key2;
}
public Tkey1 Key1 { get; set; }
public Tkey2 Key2 { get; set; }
public override int GetHashCode()
{
return Key1.GetHashCode() ^ Key2.GetHashCode();
}
public override bool Equals(object obj)
{
KeyPair<Tkey1, Tkey2> o = obj as KeyPair<Tkey1, Tkey2>;
if (o == null)
return false;
else
return Key1.Equals(o.Key1) && Key2.Equals(o.Key2);
}
}
', b);
}
}
', b);
values[key] = 555;
To encapsulate this a bit better you could wrap the dictionary:
为了更好地封装它,您可以包装字典:
public class KeyPairDictonary<Tkey1, Tkey2, Tvalue>
: Dictionary<KeyPair<Tkey1, Tkey2>, Tvalue>
{
public Tvalue this[Tkey1 key1, Tkey2 key2]
{
get
{
return this[new KeyPair<Tkey1, Tkey2>(key1, key2)];
}
set
{
this[new KeyPair<Tkey1, Tkey2>(key1, key2)] = value;
}
}
}
To make this more robust, encapsulate the composite key as a type, e.g. a class that contains the two fields, ensuring you override the Equals() and GetHashCode() methods correctly.
为了使其更健壮,将复合键封装为一种类型,例如包含两个字段的类,确保您正确覆盖 Equals() 和 GetHashCode() 方法。
回答by AndreasN
You need a key class for the Dictonary
that implements GetHashCode
correctly.
And you can extend Dictonary
to let you access it in a friendly way.
您需要一个正确Dictonary
实现的关键类GetHashCode
。并且您可以扩展Dictonary
以让您以友好的方式访问它。
The KeyPair
class:
本KeyPair
类:
KeyPairDictonary<int, bool, string> dict =
new KeyPairDictonary<int, bool, string>();
dict[1, false] = "test";
string test = dict[1, false];
Extend Dictonary<>
:
扩展Dictonary<>
:
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;
}
}
}
You can use it like this:
你可以这样使用它:
##代码##回答by AndreasN
I'd suggest a slight variation on jachymko's solution which will allow you to avoid creating a class for key pairs. Instead, wrap a private dictionary of dictionaries, as so:
我建议对 jachymko 的解决方案稍作修改,这样您就可以避免为密钥对创建一个类。相反,包装一个私人字典字典,如下所示:
##代码##