2010-01-03 16 views
11

J'ai une liste de ~ 9000 produits, et certains d'entre eux peuvent avoir des doublons. Je voulais faire une table de hachage de ces produits avec le numéro de série du produit comme clé afin que je puisse facilement trouver des doublons.Comment utiliser Hashtables/HashSets dans .NET?

Comment pourrait-on utiliser un HashTable en C#/.NET? Un HashSet serait-il plus approprié?

Finalement, je voudrais une liste comme:

-série clé: 11110 - Contient: Product1
-série clé: 11111 - Contient: Product3, produit6, Product7
-série clé: 11112 - Contient: produit4
-série clé: 11113 - Contient: Product8, Product9

Alors, j'ai une liste de tous les produits, et ils sont regroupés par ceux qui ont des numéros de série en double. Quelle est la "bonne" façon de faire cela?

Répondre

1

Vous devez d'abord définir votre «clé primaire» comme étant un ensemble de champs propres à chaque objet. Je suppose que Key-Serial ferait partie de cet ensemble, mais il doit y en avoir d'autres. Une fois que vous avez défini cette clé primaire, vous pouvez définir une structure qui représente un Key Value et l'utiliser comme clé d'un dictionnaire contenant vos produits.

Exemple:

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

Je pense que la classe Dictionary est recommandé pour des trucs comme ça.

ce serait quelque chose comme ça dans votre cas

Dictionary<string, List<Product>> 

(en utilisant la chaîne de série comme la clé)

+0

C'est un kludge, comment pourriez-vous choisir le bon produit de la liste? Il n'y a pas de substitut à une clé unique. –

+7

Pourquoi est-ce un kludge? La question portait sur le regroupement des produits par série. C'est une réponse simple, simple et lisible qui répond aux exigences, non? –

6

Un dictionnaire générique serait SUÍTE ce mieux, je pense. Code pourrait ressembler à ceci:

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

Hashtable est une sorte de dictionnaire, et un HashSet est une sorte de jeu. Ni les dictionnaires ni les ensembles ne résolvent directement votre problème - vous avez besoin d'une structure de données qui contient plusieurs objets pour une clé.

Ces bases de données sont souvent appelées multimappes. Vous pouvez en créer un en utilisant simplement une hashtable où le type de clés est un entier et les types de valeurs sont des ensembles quelconques (par exemple, hashsets ...). Vous pouvez également examiner les solutions multimap existantes, telles que: multimap in .NET. Pour plus d'informations sur l'utilisation des hashtables, vous pouvez consulter MSDN: http://msdn.microsoft.com/en-us/library/system.collections.hashtable.aspx, et il existe de nombreux autres didacticiels - effectuez une recherche sur "HashTable" ou "Dictionary".

0

Si vous vouliez avoir simplement une liste de doublons, vous pouvez:

  • prendre créer une Dictionary<T> de vos entrées de table (appelons-le IEnumerable<T> (qui ne tient pas compte des clés en double)

  • créer Hashset<T> de la même IEnumerable<T> (qui conserve les clés en double, tant que la ligne entière n'est pas la même)

  • puis de parcourir dictionary.Values, appelant hashset.Remove(value) pour chaque valeur

Qu'est-ce qui reste dans le hashset est les doublons.

1

Une excellente option maintenant disponible dans .NET est la classe Lookup. De la documentation MSDN:

Une recherche (Of TKey, TElement) ressemble à un dictionnaire (Of TKey, TValue). La différence est qu'un dictionnaire (Of TKey, TValue) mappe des clés à des valeurs uniques, alors qu'une recherche (Of TKey, TElement) mappe des clés à des collections de valeurs.

Il ya are some differences entre une recherche et un dictionnaire (de liste). À savoir, la recherche est immuable (impossible d'ajouter ou de supprimer des éléments ou des clés après sa création). Selon la façon dont vous envisagez d'utiliser vos données, la recherche peut être avantageuse compared to GroupBy().