Ответ 1
Я думаю, что словарь - рекомендуемый класс для таких вещей.
в вашем случае это будет что-то подобное
Dictionary<string, List<Product>>
(используя последовательную строку как ключ)
У меня есть список из ~ 9000 продуктов, и некоторые из них могут иметь дубликаты.
Я хотел сделать HashTable этих продуктов с серийным номером продукта в качестве своего ключа, чтобы я мог легко найти дубликаты.
Как можно использовать HashTable в С#/. NET? Будет ли HashSet более уместным?
В конце концов мне бы понравился список:
Key-Serial: 11110 - Содержит: Product1
Key-Serial: 11111 - Содержит: Product3, Product6, Product7
Key-Serial: 11112 - Содержит: Product4
Key-Serial: 11113 - Содержит: Product8, Product9
Итак, у меня есть список всех продуктов, и они сгруппированы по тем, у которых есть повторяющиеся серийные номера. Каков "правильный" способ сделать это?
Я думаю, что словарь - рекомендуемый класс для таких вещей.
в вашем случае это будет что-то подобное
Dictionary<string, List<Product>>
(используя последовательную строку как ключ)
Хэш-таблица - это своего рода словарь, а хешсет - это своего рода набор. Ни словари, ни наборы напрямую не решают вашу проблему - вам нужна структура данных, которая содержит несколько объектов для одного ключа.
Такие базы данных часто называют мультимапами. Вы можете создать его, просто используя хеш-таблицу, где тип ключей является целым числом, а типы значений - это некоторые виды (например, хэшеты...).
В качестве альтернативы вы можете посмотреть существующие многомарочные решения, например, здесь: multimap в .NET.
Информацию об использовании хэш-таблиц вы можете проверить в MSDN: http://msdn.microsoft.com/en-us/library/system.collections.hashtable.aspx, и есть много других обучающих программ - поиск используя "HashTable" или "Словарь".
Как мне кажется, общий словарь подойдет именно так. Код может выглядеть примерно так:
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}));
}
Сначала вам нужно определить свой "первичный ключ" как бы, набор полей, которые уникальны для каждого объекта. Я думаю, 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)];
}
}
Отличным вариантом, доступным в .NET, является класс Lookup. Из документации MSDN:
Поиск (из TKey, TElement) напоминает словарь (TKey, TValue). Разница заключается в том, что словарь (Of TKey, TValue) сопоставляет ключи с одиночными значениями, тогда как Lookup (Of TKey, TElement) отображает ключи в коллекции значений.
Там есть некоторые различия между Lookup и Dictionary (Of List). А именно, Lookup неизменен (не может добавлять или удалять элементы или ключи после его создания). В зависимости от того, как вы планируете использовать свои данные, Lookup может быть выгодным по сравнению с GroupBy().
Если вы хотите просто иметь список дубликатов, вы можете:
создайте Dictionary<T>
ваших записей в таблице (позвоните ему IEnumerable<T>
(который игнорирует дубликаты клавиш)
создайте Hashset<T>
того же IEnumerable<T>
(который сохраняет повторяющиеся ключи, если вся строка не одинаковая)
dictionary.Values
, вызывая hashset.Remove(value)
для каждого значенияТо, что осталось в hashset
, - это дубликаты.