C# 数组字典

5
我可以使用C# Dictionary类似于数组吗?
Dictionary<double[],double[]>

我担心它无法判断数组是否相等...

编辑:
字典中的哈希方法会很好地处理数组吗?还是只是哈希它们的引用?


2
如果你能满足我的好奇心,那么让键是一个数组的业务需求是什么? - Anthony Pegram
我正在一个分类问题中收集输入输出对(维度较大),在训练分类器之前,重复的对会以某种方式进行平均。 - Betamoo
3个回答

5

对于数组键,字典会使用引用进行哈希和相等性比较,这可能不是您想要的。这让你面临两个选择:实现一个double[]的包装类,或者(更好的选择)编写一个实现IEqualityComparer的类,并将其传递给Dictionary<T, T>构造函数。


5
@BlueRaja,一个List<T>会对其内容进行相等比较和哈希吗?我认为它不会。 - JSBձոգչ

3

仅对数组引用进行比较。在以下示例中,尽管数组a和b具有相同数量的条目且条目值相等,但字典将具有2个条目:

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>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接