字典的元组或其他多键变体,但具有可置换性

问题描述 投票:0回答:3

我正在为以下问题摸不着头脑。 我想创建一个使用多个键的字典。我提出了建议将元组作为选择方法的解决方案。我认为这是一个很好的方法。然而我的问题有以下特点。我想让键“可改变”(抱歉,如果我在这里使用了错误的俚语)。我的意思如下。我希望

dict[<key1,key2>
的结果与
dict[<key2,<key1>]
相同,因为我要存储的数据对于键的顺序是不变的。

作为示例,请参阅以下代码,这当然目前不会产生我希望的结果。我希望排列键的结果与键元组的结果相同。

    Tuple<string, string> key = new Tuple<string, string>("Name1", "Name2");
    Dictionary<Tuple<string,string>, double> dict = new Dictionary<Tuple<string, string>, double>();
    dict.Add(key, 5.0);

    Console.WriteLine(dict[key]);

    Tuple<string, string> permutedKey = new Tuple<string, string>("Name2", "Name1");
    Console.WriteLine(dict[permutedKey]);

这一切的原因是,我必须存储数据,这些数据必须使用两个键进行索引,但本质上总是对称的。所以没有必要存储两次。

c# dictionary key tuples
3个回答
4
投票

您可以定义自己的自定义相等比较器并在字典中使用它:

class TupleComparer<T> : IEqualityComparer<Tuple<T, T>>
{
    public bool Equals(Tuple<T, T> x, Tuple<T, T> y)
    {
        return object.Equals(x.Item1, y.Item1) && object.Equals(x.Item2, y.Item2) ||
               object.Equals(x.Item1, y.Item2) && object.Equals(x.Item2, y.Item1);
    }

    public int GetHashCode(Tuple<T, T> obj)
    {
        return obj.Item1.GetHashCode() + obj.Item2.GetHashCode();
    }
}

然后,您可以创建字典并向其传递比较器的实例:

Tuple<string, string> key = new Tuple<string, string>("Name1", "Name2");

Dictionary<Tuple<string,string>, double> dict = 
    new Dictionary<Tuple<string, string>, double>(new TupleComparer<string>());

dict.Add(key, 5.0);
Console.WriteLine(dict[key]);

var permutedKey = new Tuple<string, string>("Name2", "Name1");
Console.WriteLine(dict[permutedKey]);

2
投票

您需要使用两个元素定义自己的类并实现 IComparable,其中 CompareTo 将根据您的要求编写。然后使用该类作为字典的键。另外,也请重写方法 GetHashCode。


0
投票

比较

List<string>
对于您的用例来说是一个可行的选择吗?如果是这样,我推荐这个堆栈溢出答案:

比较两个

List<T>
对象是否相等,忽略顺序

如果你不能使用

List<string>
,那么我同意rbaghbanli的回答。

© www.soinside.com 2019 - 2024. All rights reserved.