【问题标题】:An integer array as a key for Dictionary一个整数数组作为字典的键
【发布时间】:2013-01-17 18:16:05
【问题描述】:

我希望有一个使用整数数组作为键的字典,如果整数数组具有相同的值(甚至不同的对象实例),它们将被视为相同的键。我该怎么做?

以下代码不起作用,因为b 是不同的对象实例。

 int[] a = new int[] { 1, 2, 3 };
 int[] b = new int[] { 1, 2, 3 };
 Dictionary<int[], string> dic = new Dictionary<int[], string>();
 dic.Add(a, "haha");
 string output = dic[b];

【问题讨论】:

标签: c# arrays


【解决方案1】:

您可以创建一个IEqualityComparer 来定义字典应该如何比较项目。如果项目的顺序是相关的,那么这样的事情应该可以工作:

public class MyEqualityComparer : IEqualityComparer<int[]>
{
    public bool Equals(int[] x, int[] y)
    {
        if (x.Length != y.Length)
        {
            return false;
        }
        for (int i = 0; i < x.Length; i++)
        {
            if (x[i] != y[i])
            {
                return false;
            }
        }
        return true;
    }

    public int GetHashCode(int[] obj)
    {
        int result = 17;
        for (int i = 0; i < obj.Length; i++)
        {
            unchecked
            {
                result = result * 23 + obj[i];
            }
        }
        return result;
    }
}

然后在创建字典时将其传入:

Dictionary<int[], string> dic
    = new Dictionary<int[], string>(new MyEqualityComparer());

注意:这里得到的哈希码计算: What is the best algorithm for an overridden System.Object.GetHashCode?

【讨论】:

  • 为什么需要GetHashCode而不是Equal运算符?
  • @william007 因为Dictionary&lt;,&gt; 维护其键的哈希表,因此必须有一个尊重新EqualsGetHashCode。同理,IEqualityComparer&lt;&gt;接口要求你做GetHashCode
  • 为什么叫它My EqualityComparer?它是你的事实是无关紧要的。它应该被称为IntArrayEqualityComparer 或类似的东西:)
  • 为什么GetHashCode()不能简单的返回obj.GetHashCode()?
  • @SimonHewitt 因为哈希码必须遵循这样的规则:如果两个对象为x.Equals(y) 返回真,那么x.GetHashCode() == y.GetHashCode() 也必须为真。使用obj.GetHashCode() 将无法实现该承诺,因为您有一个Equals 的自定义实现,您将用于比较,因此您最终会得到x.Equals(y) == truex.GetHashCode() != y.GetHashCode(),这在正确的哈希码实现中是非法的..
【解决方案2】:

也许你应该考虑使用元组

var myDictionary = new Dictionary<Tuple<int,int>, string>(); 
myDictionary.Add(new Tuple<int,int>(3, 3), "haha1"); 
myDictionary.Add(new Tuple<int,int>(5, 5), "haha2"); 

根据MSDN ,Tuple 对象Equals 方法将使用两个Tuple 对象的值

【讨论】:

  • 不能扩展到不同长度的数组
【解决方案3】:

如果您不关心实际散列,最简单的方法可能就是将数组转换为字符串。添加空格以避免数字加入。

dic.Add(String.Join(" ",a), "haha");

【讨论】:

  • dic.Add(String.Join("", new int[] {1, 2, 3}), "haha"); dic.Add(String.Join("", new int[] {12, 3}), "这失败了");
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-05
  • 2015-02-20
  • 2021-07-17
  • 2021-01-21
  • 2012-10-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多