Який найефективніший спосіб зберігати список рядків, ігноруючи дублікати? Я думав, що словник може найкраще вставити рядки, написавши dict [str] = false; і перерахування за допомогою клавіш у вигляді списку. Це хороше рішення?
Який найефективніший спосіб зберігати список рядків, ігноруючи дублікати? Я думав, що словник може найкраще вставити рядки, написавши dict [str] = false; і перерахування за допомогою клавіш у вигляді списку. Це хороше рішення?
Відповіді:
Якщо ви використовуєте .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
HashSet
втратить порядок предметів. Функція aList
надає.