Как использовать Hashtables/HashSets в .NET?

У меня есть список из ~ 9000 продуктов, и некоторые из них могут иметь дубликаты.

Я хотел сделать HashTable этих продуктов с серийным номером продукта в качестве своего ключа, чтобы я мог легко найти дубликаты.

Как можно использовать HashTable в С#/. NET? Будет ли HashSet более уместным?

В конце концов мне бы понравился список:

Key-Serial: 11110 - Содержит: Product1
Key-Serial: 11111 - Содержит: Product3, Product6, Product7
Key-Serial: 11112 - Содержит: Product4
Key-Serial: 11113 - Содержит: Product8, Product9

Итак, у меня есть список всех продуктов, и они сгруппированы по тем, у которых есть повторяющиеся серийные номера. Каков "правильный" способ сделать это?

Ответ 1

Я думаю, что словарь - рекомендуемый класс для таких вещей.

в вашем случае это будет что-то подобное

Dictionary<string, List<Product>>

(используя последовательную строку как ключ)

Ответ 2

Хэш-таблица - это своего рода словарь, а хешсет - это своего рода набор. Ни словари, ни наборы напрямую не решают вашу проблему - вам нужна структура данных, которая содержит несколько объектов для одного ключа.

Такие базы данных часто называют мультимапами. Вы можете создать его, просто используя хеш-таблицу, где тип ключей является целым числом, а типы значений - это некоторые виды (например, хэшеты...).

В качестве альтернативы вы можете посмотреть существующие многомарочные решения, например, здесь: multimap в .NET.

Информацию об использовании хэш-таблиц вы можете проверить в MSDN: http://msdn.microsoft.com/en-us/library/system.collections.hashtable.aspx, и есть много других обучающих программ - поиск используя "HashTable" или "Словарь".

Ответ 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

Сначала вам нужно определить свой "первичный ключ" как бы, набор полей, которые уникальны для каждого объекта. Я думаю, 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)];
    }
}

Ответ 5

Отличным вариантом, доступным в .NET, является класс Lookup. Из документации MSDN:

Поиск (из TKey, TElement) напоминает словарь (TKey, TValue). Разница заключается в том, что словарь (Of TKey, TValue) сопоставляет ключи с одиночными значениями, тогда как Lookup (Of TKey, TElement) отображает ключи в коллекции значений.

Там есть некоторые различия между Lookup и Dictionary (Of List). А именно, Lookup неизменен (не может добавлять или удалять элементы или ключи после его создания). В зависимости от того, как вы планируете использовать свои данные, Lookup может быть выгодным по сравнению с GroupBy().

Ответ 6

Если вы хотите просто иметь список дубликатов, вы можете:

  • создайте Dictionary<T> ваших записей в таблице (позвоните ему IEnumerable<T> (который игнорирует дубликаты клавиш)

  • создайте Hashset<T> того же IEnumerable<T> (который сохраняет повторяющиеся ключи, если вся строка не одинаковая)

  • а затем перейдите через dictionary.Values, вызывая hashset.Remove(value) для каждого значения

То, что осталось в hashset, - это дубликаты.