多键散列或字典,作为输出的值列表
本文关键字:输出 列表 字典 | 更新日期: 2023-09-27 18:10:38
我是c#新手,需要一个包含多个键的通用列表。
我有三个参数来创建数据的键。对于每条记录(每三个键),我都有一组值。
我需要有一个泛型列表,列表中每个节点的值是我的键的值,每个节点的值指向包含该键的相关值的列表。
下面是我的数据和数据结构的例子,我正在寻找:
Key1 Key2 Key3 Value1 Value2 Value3
0 0 0 a b c
0 0 1 d e f
0 1 1 g h -
<0,0,0, List(a,b,c)> ---> <0,0,1,list(d,e,f)>---> <0,1,1,List(g,h)>--->Null
我想有一个哈希表,有多个键和指向一个对象的值,这是一个链接列表。或者用这三个键创建一个字典,并再次返回指向链表头的指针。
如果有人能告诉我如何在c#中做到这一点,我将不胜感激。
首先,您肯定应该使用Dictionary<TKey, TValue>
,而不是HashTable
。非泛型集合类型实际上只是为了向后兼容而存在。对于新代码,最好使用泛型类型。
对于您的特定问题,您将注意到. net字典类型只允许一个键。实际上,这通常是字典集合的典型情况。集合中的每个条目都是一个键/值对。
但是,您可以将三个键值组合为单个对象值并将其用作键。事实上,. net提供了各种Tuple
类来完成这一点,对于类型参数的每个计数都有不同的类,因此对于对象中的每个项计数都有不同的类。此外,这些类都实现了适当的比较和散列,用作字典键。
现在,把这个应用到你的问题中,你有一些选择,这取决于你真正想做什么。不幸的是,你想做什么并不清楚。(
如果每个键值三元组最多只能有三个值,那么我认为评论者Mephy的建议很好。你可以像这样声明你的集合并初始化它:
Dictionary<Tuple<int, int, int>, Tuple<string, string, string>> collection =
new Dictionary<Tuple<int, int, int>, Tuple<string, string, string>>
{
{ Tuple.Create(0, 0, 0), Tuple.Create("a", "b", "c") },
{ Tuple.Create(0, 0, 1), Tuple.Create("d", "e", "f") },
{ Tuple.Create(0, 1, 1), Tuple.Create("g", "h", null) },
};
注意,null
用于表示字典的值元组中缺少的值。
然而,如果你真的想要一个列表对象作为值,你可以这样做:
Dictionary<Tuple<int, int, int>, List<string>> collection =
new Dictionary<Tuple<int, int, int>, List<string>>
{
{ Tuple.Create(0, 0, 0), new List<string> { "a", "b", "c"} },
{ Tuple.Create(0, 0, 0), new List<string> { "d", "e", "f"} },
{ Tuple.Create(0, 0, 0), new List<string> { "g", "h" } },
};
至于将上述作为键/值对列表处理,就像任何。net集合类型一样,Dictionary<TKey, TValue>
可以被视为值的枚举,在这种情况下通过IEnumerable<KeyValuePair<TKey, TValue>>
的实现,其中TKey
和TValue
是用于字典对象本身的相同类型。例如,你可以这样做:
foreach (KeyValuePair<Tuple<int, int, int>, List<string>> kvp in collection)
{
// here, kvp.Key will have the Tuple<int, int, int> key value
// for the dictionary entry, while kvp.Value will have the
// List<string> value for the same entry.
}
注意,. net中字典类型的枚举顺序是未定义的。你并没有得到任何保证元素会按任何特定的顺序返回,例如按它们被添加的顺序返回。如果你需要一个特定的订单,你必须以某种方式强迫自己。
最后,注意上面示例中的KeyValuePair<TKey, TValue>
类型。这实际上只是元组的一种特殊情况(尽管它早于。net中实际的Tuple...
类)。也就是说,它是专门为存储键/值对而设计的自定义类。
如果您愿意,您可以自己声明这样的类型作为字典的键。这样做的好处是允许您为类型提供一个特定的、可读的名称,当然还允许您避免处理Tuple...
类所涉及的一些冗长问题(Tuple.Create()
泛型方法有所帮助,但声明仍然可能变得笨拙)。这样做的代价当然是自己编写比较和哈希代码。
你可以找到一个中间地带,要么创建一个继承你需要的Tuple...
类的类,在这个类中你只实现构造函数(将初始化参数传递给基构造函数),例如:
class CustomKey : Tuple<int, int, int>
{
public CustomKey(int i1, int i2, int i3) : base(i1, i2, i3) { }
}
或简单地用using
指令在模块中别名Tuple...
类型,给Tuple...
类型一个本地可用的名称,更可读,例如:
using CustomKey = System.Tuple<int, int, int>;
前者使您可以轻松访问项目中的任何地方的可读名称,但确实需要实现一个(非常短的)类;后者需要较少的工作,但只适用于单个源文件。