Эффективный список уникальных строк C # - PullRequest
82 голосов
/ 28 мая 2009

Какой самый эффективный способ хранить список строк, игнорируя любые дубликаты? Я думал, что словарь может быть лучше вставлять строки, написав dict [str] = false; и перечисление через ключи в виде списка. Это хорошее решение?

Ответы [ 7 ]

103 голосов
/ 28 мая 2009

Если вы используете .NET 3.5, HashSet должен работать для вас.

Класс HashSet <(Of <(T>)>) обеспечивает высокопроизводительные операции над множествами. Множество это коллекция, которая не содержит дубликаты элементов и чьи элементы в произвольном порядке.

20 голосов
/ 28 мая 2009

Вы можете сделать что-то подобное

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);   
14 голосов
/ 13 июня 2012

Я не уверен, что это считается хорошим ответом, но, столкнувшись с необходимостью уникального набора, поддерживающего порядок вставки, я пошел на компромисс с HashSet и List рядом. В этом случае, когда вы добавляете в набор, выполните следующее:

if(hashSet.Add(item))
    orderList.Add(item);

При удалении предметов обязательно снимайте их с обоих. Таким образом, до тех пор, пока вы можете быть уверены, что ничто больше не добавит элементы в список, у вас будет уникальный набор с упорядочением вставки!

8 голосов
/ 21 февраля 2014

Используйте 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
6 голосов
/ 02 января 2018

Вы также можете использовать Linq как:

using System.Linq;

var items = new List<string>() { "one", "one", "two", "one", "two", "zero" };

List<string> distinctItems = items.Distinct().ToList();
2 голосов
/ 04 августа 2016

Вот еще одно решение без использования 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

Тестовый исходный код (сущность)

2 голосов
/ 28 мая 2009

Это не часть системного пространства имен, но использовались Iesi.Collections из http://www.codeproject.com/KB/recipes/sets.aspx с NHibernate. Он поддерживает хэшированный набор, сортированный набор, набор словарей и так далее. Так как он использовался с NHibernate, он широко и очень стабилен. Это также не требует .Net 3.5

...