2010-01-03 5 views
11

Ho una lista di ~ 9000 prodotti, alcuni dei quali potrebbero avere duplicati.Come utilizzare Hashtables/HashSets in .NET?

Volevo creare un HashTable di questi prodotti con il numero di serie del prodotto come chiave in modo da poter trovare facilmente i duplicati.

Come si può utilizzare un HashTable in C# /. NET? Un HashSet sarebbe più appropriato?

Alla fine Vorrei una lista come:

chiave-seriale: 11110 - Contiene: Product1
chiave-seriale: 11111 - Contiene: Product3, Prodotto6, Prodotto7
chiave-seriale: 11112 - Contiene: Product4
Chiave-seriale: 11113 - Contiene: Prodotto8, Prodotto9

Quindi, ho un elenco di tutti i prodotti, e sono raggruppati da quelli che hanno numeri seriali duplicati. Qual è il modo "corretto" per farlo?

risposta

1

Per prima cosa è necessario definire la "Chiave primaria" come se fosse una serie di campi che sono univoci per ciascun oggetto. Immagino che lo Key-Serial faccia parte di quel set, ma ce ne devono essere altri. Una volta definita la 'Chiave primaria', è possibile definire una struttura che rappresenta uno Key Value e utilizzarla come chiave per un dizionario contenente i prodotti.

Esempio:

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

Penso dizionario è la classe consigliata per cose come questa.

sarebbe qualcosa di simile nel tuo caso

Dictionary<string, List<Product>> 

(usando stringa seriale come chiave)

+0

Questo è un kludge, come hai potuto scegliere il prodotto giusto dalla lista? Non c'è sostituto per una chiave unica. –

+7

Perché si tratta di un kludge? La domanda riguardava il raggruppamento dei prodotti in serie. Questa è una risposta semplice, semplice e leggibile che soddisfa i requisiti, no? –

6

Un Dizionario generico sarebbe Suite Questa migliore, credo. Codice potrebbe essere qualcosa di simile:

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 tabella hash è una sorta di dizionario, e un hashset è una sorta di set. Né dizionari né set risolvono direttamente il tuo problema: hai bisogno di una struttura dati che contenga più oggetti per una chiave.

Tali database sono spesso denominati multimaps. Puoi crearne uno semplicemente usando una tabella hash in cui il tipo di chiavi sono numeri interi e i tipi di valori sono insiemi di qualche tipo (ad esempio, hashset ...).

In alternativa, è possibile esaminare le soluzioni multimap esistenti, ad esempio: multimap in .NET.

Per informazioni sull'utilizzo di hashtables, è possibile verificarlo su MSDN: http://msdn.microsoft.com/en-us/library/system.collections.hashtable.aspx e ci sono un sacco di altri tutorial: cercare utilizzando "HashTable" o "Dizionario".

0

Se si voleva avere semplicemente un elenco di duplicati, si potrebbe:

  • prendere creare un Dictionary<T> delle vostre voci della tabella (chiamiamolo IEnumerable<T> (che ignora chiavi duplicate)

  • creare a Hashset<T> dello stesso IEnumerable<T> (che mantiene le chiavi duplicate, purché l'intera riga non sia la stessa)

  • e quindi itera fino a dictionary.Values, chiamando hashset.Remove(value) per ogni valore

Ciò che resta nei hashset sono i duplicati.

1

Un'ottima opzione ora disponibile in .NET è la classe Lookup. Dalla documentazione MSDN:

Una ricerca (di TKey, TElement) è simile a un dizionario (di TKey, TValue). La differenza è che un dizionario (di TKey, TValue) mappa le chiavi su valori singoli, mentre una ricerca (di TKey, TElement) mappa le chiavi in ​​raccolte di valori.

C'è are some differences tra una ricerca e un dizionario (di elenco). Vale a dire, la ricerca è immutabile (non è possibile aggiungere o rimuovere elementi o chiavi dopo la sua creazione). A seconda di come si prevede di utilizzare i dati, la ricerca potrebbe essere vantaggiosa compared to GroupBy().

Problemi correlati