2010-05-25 58 views
5

我可以使用类似数组的C#字典吗?C#字典的数组

Dictionary<double[],double[]> 

恐怕也不会能够告诉当数组相等......

编辑:
将在字典中的散列法采取精心呵护阵列?或者只是散列它们的引用?

+2

如果您能满足我的好奇心,那么将密钥设为数组的业务需求是什么? – 2010-05-25 20:37:34

+0

我正在收集输入 - 输出对(大维度)在分类问题中,其中重复的对在训练分类器之前以某种方式进行平均... – Betamoo 2010-05-25 20:41:26

回答

5

对于数组键,字典将散列和平等的引用,这可能不是你想要的。这给你两个选择:实现double[]的包装类,或者(更好)写一些实现IEqualityComparer的东西,并将它传递给构造函数Dictionary<T, T>

+5

@BlueRaja,做了一个'List '对其内容进行等式比较和散列?我不认为它确实如此。 – 2010-05-25 20:45:45

3

只有数组引用将被比较。在下面的例子中,字典将具有条目即使数组a和b具有相同数目的条目和输入值是相等的:

double[] a = new[] { 1.0, 2.1, 3.2 }; 
double[] b = new[] { 1.0, 2.1, 3.2 }; 

Dictionary<double[], double[]> d = new Dictionary<double[], double[]>(); 

d[a] = new [] { 1.1 }; 
d[b] = new [] { 2.2 }; 

Console.WriteLine(d.Count); 
Console.WriteLine(d[b][0]); 
0

我不认为具有阵列作为密钥是一个好主意,尤其是如果它很大,并且您的相等逻辑基于数组的内容。因为每次你打电话给GetHashCode,它都必须对整个阵列进行计算,如果阵列很大,可能需要一些时间......

解决方法是将数组包装到一个类中,该类将存储哈希码,直到数据被修改,使得它每一次不重新计算:

class ArrayWrapper<T> 
{ 
    private T[] _array; 
    public ArrayWrapper(T[] array) 
    { 
     _array = array; 
    } 

    private int? _hashcode; 
    public override int GetHashCode() 
    { 
     if (!_hashcode.HasValue) 
     { 
      _hashcode = ComputeHashCode(); 
     } 
     return _hashcode.Value; 
    } 

    public override bool Equals(object other) 
    { 
     // Your equality logic here 
    } 

    protected virtual int ComputeHashCode() 
    { 
     // Your hashcode logic here 
    } 

    public int Length 
    { 
     get { return _array.Length; } 
    } 

    public T this[int index] 
    { 
     get { return _array[index]; } 
     set 
     { 
      _array[index] = value; 
      // Invalidate the hashcode when data is modified 
      _hashcode = null; 
     } 
    } 
} 

所以你的字典将是一个Dictionary<ArrayWrapper<double>, ArrayWrapper<double>>。当然,您可能需要向封装添加一些方法或属性(例如实现IList<T>