2010-01-03 27 views
11

Tengo una lista de ~ 9000 productos, y algunos de los cuales pueden tener duplicados.¿Cómo uso Hashtables/HashSets en .NET?

Quería hacer un HashTable de estos productos con el número de serie del producto como clave para que pueda encontrar los duplicados fácilmente.

¿Cómo se puede utilizar una HashTable en C# /. NET? ¿Sería un HashSet más apropiado?

Finalmente me gustaría una lista como:

Key-Serial: 11110 - Contiene: producto1
Key-Serial: 11111 - Contiene: Product3, producto6, Product7
Key-Serial: 11112 - Contiene: Producto4
Número de serie: 11113 - Contiene: Producto8, Producto9

De modo que tengo una lista de todos los productos, y están agrupados por los que tienen números de serie duplicados. ¿Cuál es la forma "correcta" de hacer esto?

Respuesta

1

Primero tiene que definir su 'Clave principal' por así decirlo, un conjunto de campos que son únicos para cada objeto. Supongo que Key-Serial sería parte de ese conjunto, pero debe haber otros. Una vez que defina esa 'Clave primaria', puede definir una estructura que represente un Key Value y usarla como la clave de un diccionario que contenga sus productos.

Ejemplo:

struct ProductPrimaryKey 
{ 
    public string KeySerial; 
    public string OtherDiscriminator; 

    public ProductPrimaryKey(string keySerial, string otherDiscriminator) 
    { 
     KeySerial = keySerial; 
     OtherDiscriminator = otherDiscriminator; 
    } 
} 

class Product 
{ 
    public string KeySerial { get; set; } 
    public string OtherDiscriminator { get; set; } 
    public int MoreData { get; set; } 
} 

class DataLayer 
{ 
    public Dictionary<ProductPrimaryKey, Product> DataSet 
     = new Dictionary<ProductPrimaryKey, Product>(); 

    public Product GetProduct(string keySerial, string otherDiscriminator) 
    { 
     return DataSet[new ProductPrimaryKey(keySerial, otherDiscriminator)]; 
    } 
} 
9

Creo diccionario es la clase recomendada para este tipo de cosas.

sería algo como esto en su caso

Dictionary<string, List<Product>> 

(usando un cordón de serie como la clave)

+0

Que es un kludge, ¿cómo podría elegir el producto correcto de la lista? No hay sustituto para una clave única. –

+7

¿Por qué es esto un kludge? La pregunta era sobre agrupar productos por serial. Esta es una respuesta sencilla, simple y legible que cumple con los requisitos, ¿no? –

6

un diccionario genérico sería Suite Esta mejor, creo. Código podría ser algo como esto:

var keyedProducts = new Dictionary<int,List<string>>(); 

foreach (var keyProductPair in keyProductPairs) 
{ 
    if (keyedProducts.Contains(keyProductPair.Key)) 
    keyedProducts[keyProductPair.Key].Add(keyProductPair.Product); 
    else 
    keyedProducts.Add(keyProductPair.Key, new List<string>(new[]{keyProductPair.Product})); 
} 
7

Una tabla hash es una especie de diccionario, y una hashset es una especie de juego. Ni los diccionarios ni los conjuntos resuelven directamente su problema; usted necesita una estructura de datos que contenga múltiples objetos para una clave.

Tales bases de datos a menudo se llaman multimaps. Puede crear uno simplemente usando una tabla hash donde el tipo de claves son enteros y los tipos de valores son conjuntos de algún tipo (por ejemplo, hashsets ...).

Alternativamente, puede ver soluciones multimapa existentes, como aquí: multimap in .NET.

Para obtener información sobre el uso de tablas hash, puede verificarlo en MSDN: http://msdn.microsoft.com/en-us/library/system.collections.hashtable.aspx, y hay muchos otros tutoriales, busque utilizando "HashTable" o "Diccionario".

0

Si quería tener simplemente una lista de duplicados, usted podría:

  • tomar crear un Dictionary<T> de sus entradas de la tabla (vamos a llamarlo IEnumerable<T> (que ignora claves duplicadas)

  • crear un Hashset<T> del mismo IEnumerable<T> (que conserva las claves duplicadas, siempre que toda la fila no sea la misma)

  • y luego itere a través de dictionary.Values, llamando al hashset.Remove(value) para cada valor

Lo que queda en el hashset son los duplicados.

1

Una gran opción ahora disponible en .NET es la clase Lookup. De la documentación de MSDN:

Una búsqueda (de TKey, TElement) se asemeja a un diccionario (de TKey, TValue). La diferencia es que un diccionario (de TKey, TValue) asigna claves a valores únicos, mientras que una búsqueda (de TKey, TElement) asigna claves a colecciones de valores.

Hay are some differences entre una búsqueda y un diccionario (de la lista). A saber, la búsqueda es inmutable (no se pueden agregar o eliminar elementos o claves una vez creada). Dependiendo de cómo planea usar sus datos, la búsqueda puede ser ventajosa compared to GroupBy().

Cuestiones relacionadas