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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1995885/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 22:30:07  来源:igfitidea点击:

How do I use Hashtables/HashSets in .NET?

c#.netdata-structureshashtablehashset

提问by Biro

I have a list of ~9000 products, and some of which may have duplicates.

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

I wanted to make a HashTable of these products with the products serial number as their key so I can find duplicates easily.

我想为这些产品制作一个哈希表,以产品序列号为关键字,这样我就可以轻松找到重复项。

How would one go about using a HashTable in C#/.NET? Would a HashSet be more appropriate?

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

Eventually I would like a list like:

最终我想要一个列表:

Key-Serial: 11110 - Contains: Product1
Key-Serial: 11111 - Contains: Product3, Product6, Product7
Key-Serial: 11112 - Contains: Product4
Key-Serial: 11113 - Contains: Product8, Product9

密钥序列:11110 - 包含:产品 1
密钥序列:11111 - 包含:产品 3、产品 6、产品 7
密钥序列:11112 - 包含:产品 4
密钥序列:11113 - 包含:产品 8、产品 9

So, I have a list of all products, and they are grouped by the ones that have duplicate serial numbers. What is the "correct" way to do this?

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

回答by Aviad P.

First you need to define your 'Primary Key' as it were, a set of fields that are unique to each object. I guess Key-Serialwould be part of that set, but there must be others. Once you define that 'Primary Key' you can define a struct that represents a Key Valueand use that as the key to a dictionary containing your products.

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

Example:

例子:

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

回答by peter p

I think Dictionary is the recommended class for stuff like this.

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

it would be something like this in your case

在你的情况下会是这样

Dictionary<string, List<Product>>

(using serial string as key)

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

回答by James Kolpack

A generic Dictionary would suite this best, I think. Code might look something like this:

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

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

回答by Oak

A hashtable is a kind of dictionary, and a hashset is a kind of set. Neither dictionaries nor sets directly solve your problem - you need a data structure which holds multiple objects for one key.

哈希表是一种字典,哈希集是一种集合。字典和集合都不能直接解决你的问题——你需要一个数据结构,它可以为一个键保存多个对象。

Such databases are often called multimaps. You can create one by simply using a hashtable where the type of keys are integers and the types of values are sets of some kind (for example, hashsets...).

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

Alternatively, you can look at existing multimap solutions, such as here: multimap in .NET.

或者,您可以查看现有的多映射解决方案,例如此处: .NET 中的多映射

For information on using hashtables, you can check it out on MSDN: http://msdn.microsoft.com/en-us/library/system.collections.hashtable.aspx, and there are plenty of other tutorials - search on using either "HashTable" or "Dictionary".

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

回答by Christopher Stevenson

If you wanted to simply have a list of duplicates, you could:

如果你只想有一个重复的列表,你可以:

  • take create a Dictionary<T>of your table entries (let's call it IEnumerable<T>(which ignores duplicate keys)

  • create a Hashset<T>of the same IEnumerable<T>(which keeps duplicate keys, as long as the entire row isn't the same)

  • and then iterate through dictionary.Values, calling hashset.Remove(value)for each value
  • 采取创建Dictionary<T>您的表条目(让我们称之为IEnumerable<T>(忽略重复键)

  • 创建Hashset<T>相同的IEnumerable<T>(保留重复键,只要整行不相同)

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

What's left in the hashsetis the duplicates.

剩下的hashset是重复项。

回答by Zairja

A great option now available in .NET is the Lookupclass. From the MSDN documentation:

现在在 .NET 中可用的一个很好的选择是Lookup类。从 MSDN 文档:

A Lookup(Of TKey, TElement) resembles a Dictionary(Of TKey, TValue). The difference is that a Dictionary(Of TKey, TValue) maps keys to single values, whereas a Lookup(Of TKey, TElement) maps keys to collections of values.

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

There are some differencesbetween a Lookup and Dictionary(Of List). Namely, the Lookup is immutable (can't add or remove elements or keys after it's created). Depending on how you plan to use your data, the Lookup may be advantageous compared to GroupBy().

Lookup 和 Dictionary(Of List) 之间存在一些差异。即,Lookup 是不可变的(在创建后不能添加或删除元素或键)。根据您计划如何使用数据,与 GroupBy() 相比, Lookup 可能更有利。