Эффективный список уникальных строк C#
Каков наиболее эффективный способ хранить список строк, игнорируя любые дубликаты? Я думал, что словарь может быть лучше вставлять строки, написав dict[str] = false; и перечисление через ключи в виде списка. Это хорошее решение?
7 ответов
Если вы используете.NET 3.5, HashSet должен работать на вас.
Класс HashSet<(Of <(T>)>) обеспечивает высокопроизводительные операции над множествами. Набор - это коллекция, которая не содержит повторяющихся элементов и элементы которой расположены в произвольном порядке.
Вы можете посмотреть, чтобы сделать что-то вроде этого
var hash = new HashSet<string>();
var collectionWithDup = new []{"one","one","two","one","two","zero"};
// No need to check for duplicates as the Add method
// will only add it if it doesn't exist already
foreach (var str in collectionWithDup)
hash.Add(str);
Я не уверен, что это считается хорошим ответом, но, столкнувшись с необходимостью уникального набора, который поддерживает порядок вставки, я пошел на компромисс с HashSet и List рядом. В этом случае всякий раз, когда вы добавляете в набор, сделайте следующее:
if(hashSet.Add(item))
orderList.Add(item);
При удалении предметов, обязательно удалите их из обоих. Таким образом, до тех пор, пока вы можете быть уверены, что ничто больше не добавит элементы в список, у вас будет уникальный набор с упорядочением вставки!
Вы также можете использовать Linq как в:
using System.Linq;
var items = new List<string>() { "one", "one", "two", "one", "two", "zero" };
List<string> distinctItems = items.Distinct().ToList();
Используйте HashSet, не нужно проверять.Contains(), просто добавьте свои элементы в список и, если он будет повторяться, он не будет добавлен.
HashSet<int> uniqueList = new HashSet<int>();
uniqueList.Add(1); // List has values 1
uniqueList.Add(2); // List has values 1,2
uniqueList.Add(1); // List has values 1,2
Console.WriteLine(uniqueList.Count); // it will return 2
Это не является частью пространства имен системы, но использовало Iesi.Collections с http://www.codeproject.com/KB/recipes/sets.aspx с NHibernate. Он поддерживает хэшированный набор, сортированный набор, набор словарей и т. Д. Так как он использовался с NHibernate, он широко и очень стабилен. Это также не требует.Net 3.5
Вот еще одно решение без использования HashSet
,
var items = new List<string>() { "one", "one", "two", "one", "two", "zero" };
var uniqueItems = items.Where((item, index) => items.IndexOf(item) == index);
Он был принят из этой темы: javascript - уникальные значения в массиве
Тестовое задание:
using FluentAssertions;
uniqueItems.Count().Should().Be(3);
uniqueItems.Should().BeEquivalentTo("one", "two", "zero");
Тест производительности для List
, HashSet
а также SortedSet
, 1 миллион итераций:
List: 564 ms
HashSet: 487 ms
SortedSet: 1932 ms