2010-05-25 22 views
5

¿Puedo usar C# Dictionary en clases como matrices?C# Dictionary of arrays

Dictionary<double[],double[]> 

me temo que no va a ser capaz de decir cuando arreglos son iguales ...

EDIT:
¿El procedimiento de codificación en el diccionario cuides bien de matrices? o simplemente hashing sus referencias?

+2

Si pudiera satisfacer mi curiosidad, ¿cuál es la necesidad comercial de tener la clave como una matriz? –

+0

Estoy recopilando un par de entrada-salida (de gran dimensionalidad) en un problema de clasificación, donde los pares repetidos se promedian de alguna manera antes del clasificador de entrenamiento ... – Betamoo

Respuesta

5

Para las claves de matriz, el diccionario utilizará las referencias para hashing e igualdad, que probablemente no es lo que desea. Esto te deja con dos opciones: implementar una clase contenedora para double[] o (mejor) escribir algo que implemente IEqualityComparer y pasarlo al constructor Dictionary<T, T>.

+5

@BlueRaja, ¿hace una lista 'comparación de igualdad y hash sobre su contenido? No creo que lo haga. –

3

Solo se compararán las referencias de matriz. En el siguiente ejemplo, el diccionario tendrá entradas a pesar de que las matrices A y B tienen el mismo número de entradas y los valores de entrada son iguales:

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

no creo que tiene una disposición como la clave es una buena idea, especialmente si es grande y si su lógica de igualdad se basa en el contenido de la matriz. Porque cada vez que llame al GetHashCode, tendrá que realizar cálculos en toda la matriz, lo que puede llevar algo de tiempo si la matriz es grande ...

Una solución sería envolver la matriz en una clase que almacenaría el código hash hasta que los datos se modifica, por lo que no se vuelve a calcular cada vez que:

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

lo tanto su diccionario sería un Dictionary<ArrayWrapper<double>, ArrayWrapper<double>>. Por supuesto, es posible que desee agregar algunos métodos o propiedades al contenedor (implemente IList<T> por ejemplo)