多键散列或字典,作为输出的值列表

本文关键字:输出 列表 字典 | 更新日期: 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>>的实现,其中TKeyTValue是用于字典对象本身的相同类型。例如,你可以这样做:

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>;

前者使您可以轻松访问项目中的任何地方的可读名称,但确实需要实现一个(非常短的)类;后者需要较少的工作,但只适用于单个源文件。