如何在 .NET 中使用 Hashtables/HashSets?

Posted

技术标签:

【中文标题】如何在 .NET 中使用 Hashtables/HashSets?【英文标题】:How do I use Hashtables/HashSets in .NET? 【发布时间】:2011-01-01 00:57:01 【问题描述】:

我有一个大约 9000 种产品的列表,其中一些可能有重复。

我想用产品序列号作为密钥为这些产品制作一个哈希表,以便我可以轻松找到重复项。

如何在 C#/.NET 中使用 HashTable? HashSet 会更合适吗?

最终我想要一个类似的列表:

密钥序列号:11110 - 包含:Product1 密钥序列号:11111 - 包含:Product3、Product6、Product7 密钥序列:11112 - 包含:Product4 密钥序列:11113 - 包含:Product8、Product9

所以,我有一个所有产品的列表,它们按具有重复序列号的产品分组。这样做的“正确”方法是什么?

【问题讨论】:

【参考方案1】:

我认为 Dictionary 是此类内容的推荐类。

在你的情况下会是这样的

Dictionary<string, List<Product>>

(使用串行字符串作为键)

【讨论】:

这是一个杂项,你怎么能从列表中选择合适的产品?唯一键无可替代。 为什么这是一个杂牌?问题是关于按系列对产品进行分组。这是一个直截了当、简单易读的答案,符合要求,不是吗?【参考方案2】:

hashtable 是一种字典,hashset 是一种集合。字典和集合都不能直接解决您的问题 - 您需要一个为一个键保存多个对象的数据结构。

此类数据库通常称为多图。您可以通过简单地使用哈希表来创建一个,其中键的类型是整数,值的类型是某种集合(例如,哈希集...)。

或者,您可以查看现有的多地图解决方案,例如这里: multimap in .NET.

有关使用哈希表的信息,您可以在 MSDN 上查看:http://msdn.microsoft.com/en-us/library/system.collections.hashtable.aspx,还有很多其他教程 - 搜索使用“哈希表”或“字典”。

【讨论】:

【参考方案3】:

我认为,通用字典最适合这个。代码可能如下所示:

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

【讨论】:

【参考方案4】:

.NET 现在提供的一个很好的选择是Lookup 类。来自 MSDN 文档:

Lookup(Of TKey, TElement) 类似于 Dictionary(Of TKey, TValue)。区别在于 Dictionary(Of TKey, TValue) 将键映射到单个值,而 Lookup(Of TKey, TElement) 将键映射到值的集合。

在查找和字典(列表)之间有are some differences。即,查找是不可变的(创建后不能添加或删除元素或键)。根据您计划使用数据的方式,查找可能是有利的compared to GroupBy()。

【讨论】:

【参考方案5】:

首先,您需要按原样定义您的“主键”,即每个对象唯一的一组字段。我猜Key-Serial 将是该系列的一部分,但肯定还有其他人。一旦定义了“主键”,您就可以定义一个表示 Key Value 的结构并将其用作包含您的产品的字典的键。

例子:

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)];
    

【讨论】:

【参考方案6】:

如果您想简单地列出重复项,您可以:

为你的表条目创建一个Dictionary&lt;T&gt;(我们称之为IEnumerable&lt;T&gt;(忽略重复键)

创建同一个IEnumerable&lt;T&gt;Hashset&lt;T&gt;(只要整行不一样,它就会保留重复的键)

然后遍历dictionary.Values,为每个值调用hashset.Remove(value)

hashset 中剩下的是重复项。

【讨论】:

以上是关于如何在 .NET 中使用 Hashtables/HashSets?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用在 Python 中就地修改的 .NET 方法?

如何在 VB.NET 中使用 protobuf-net 添加枚举?

如何使用 vb.net 2003 在 asp.net 1.1 中手动填充数据网格?

如何使用 Vb.net 在 Openoffice 中进行 Mailmerge

如何在 .NET 中使用 Hashtables/HashSets?

如何在 .NET 中使用 XmlWriter 创建 XmlDocument?