У кого-нибудь есть быстрый способ дедупликации универсального списка в C #?
c#
list
generics
duplicates
JC Grubbs
источник
источник
ICollection<MyClass> withoutDuplicates = new HashSet<MyClass>(inputList);
Ответы:
Возможно, вам следует рассмотреть возможность использования HashSet .
Из ссылки MSDN:
источник
HashSet
не имеет индекса , поэтому его не всегда можно использовать. Я должен создать один раз огромный список без дубликатов, а затем использовать егоListView
в виртуальном режиме. Это было очень быстро сделатьHashSet<>
сначала, а затем преобразовать его вList<>
(так чтоListView
можете получить доступ к элементам по индексу).List<>.Contains()
слишком медленноЕсли вы используете .Net 3+, вы можете использовать Linq.
источник
Как насчет:
В .net 3.5?
источник
Просто инициализируйте HashSet списком того же типа:
Или, если вы хотите вернуть список:
источник
List<T>
результатnew HashSet<T>(withDupes).ToList()
Сортируйте его, затем отметьте два и два рядом друг с другом, так как дубликаты будут объединяться.
Что-то вроде этого:
Ноты:
источник
RemoveAt
является очень дорогостоящей операциейList
Мне нравится использовать эту команду:
У меня есть эти поля в моем списке: Id, StoreName, City, PostalCode Я хотел показать список городов в выпадающем списке, который имеет повторяющиеся значения. Решение: сгруппируйте по городам, затем выберите первый в списке.
Я надеюсь, что это помогает :)
источник
Это сработало для меня. просто используйте
Замените «Тип» на желаемый тип, например, int.
источник
Как сказал кроноз в .Net 3.5, вы можете использовать
Distinct()
.В .Net 2 вы можете имитировать это:
Это может быть использовано для дедупликации любой коллекции и будет возвращать значения в исходном порядке.
Обычно фильтровать коллекцию намного быстрее (как
Distinct()
и в этом примере), чем удалять из нее элементы.источник
HashSet
конструктор дедуплицировал, что делает его лучше для большинства обстоятельств. Тем не менее, это сохранит порядок сортировки, чегоHashSet
нет.Dictionary<T, object>
вместо, заменить.Contains
на.ContainsKey
и.Add(item)
с.Add(item, null)
HashSet
сохраняет порядок, покаDistinct()
нет.Метод расширения может быть приличным способом ... что-то вроде этого:
А потом позвоните вот так, например:
источник
В Java (я предполагаю, что C # более или менее идентичен):
Если вы действительно хотите изменить исходный список:
Чтобы сохранить порядок, просто замените HashSet на LinkedHashSet.
источник
var noDupes = new HashSet<T>(list); list.Clear(); list.AddRange(noDupes);
:)Это берет разные (элементы без дублирующих элементов) и снова конвертирует их в список:
источник
Примечание. Это решение не требует знания Linq, кроме того, что оно существует.
Код
Начните с добавления следующего в начало вашего файла класса:
Теперь вы можете использовать следующее для удаления дубликатов из объекта с именем
obj1
:Примечание: переименуйте
obj1
в название вашего объекта.Как это работает
Команда Union перечисляет одну из каждой записи двух исходных объектов. Поскольку obj1 - оба исходных объекта, это сводит obj1 к одной из каждой записи.
ToList()
Возвращает новый список. Это необходимо, поскольку команды Linq likeUnion
возвращают результат в виде результата IEnumerable вместо изменения исходного списка или возврата нового списка.источник
В качестве вспомогательного метода (без Linq):
источник
Если вы не заботитесь о порядке вы можете просто засунуть элементы в
HashSet
, если вы действительно хотите сохранить заказ вы можете сделать что - то вроде этого:Или Линк путь:
Edit:
HashSet
методO(N)
времени иO(N)
пространства во время сортировки , а затем сделать уникальный (как это было предложено @ lassevk и другие) этоO(N*lgN)
время иO(1)
пространство , так что это не так ясно для меня (как это было на первый взгляд) , что сортировка путь уступает (мой извиняюсь за временное отрицательное голосование ...)источник
Вот метод расширения для удаления соседних дубликатов на месте. Сначала вызовите Sort () и передайте в тот же IComparer. Это должно быть более эффективно, чем версия Лассе В. Карлсена, которая неоднократно вызывает RemoveAt (что приводит к перемещению памяти из нескольких блоков).
источник
Установив пакет MoreLINQ через Nuget, вы можете легко различать список объектов по свойству
источник
Может быть проще просто убедиться, что дубликаты не добавляются в список.
источник
List<T>.Contains
метод каждый раз, но с более чем 1 000 000 записей. Этот процесс замедляет мое приложение. Я используюList<T>.Distinct().ToList<T>()
первый вместо этого.Вы можете использовать Союз
источник
Еще один способ в .Net 2.0
источник
Есть много способов решить проблему с дубликатами в списке, ниже один из них:
Приветствия Рави Ганесан
источник
Вот простое решение, которое не требует сложного для чтения LINQ или какой-либо предварительной сортировки списка.
источник
Ответ Дэвида Дж. - хороший метод, не требующий дополнительных объектов, сортировки и т. Д. Однако его можно улучшить:
for (int innerIndex = items.Count - 1; innerIndex > outerIndex ; innerIndex--)
Таким образом, внешний цикл идет сверху вниз для всего списка, но внутренний цикл идет снизу «пока не будет достигнута позиция внешнего цикла».
Внешний цикл гарантирует, что весь список обработан, внутренний цикл находит фактические дубликаты, они могут произойти только в той части, которую внешний цикл еще не обработал.
Или, если вы не хотите делать восходящий цикл для внутреннего цикла, вы можете запустить внутренний цикл в externalIndex + 1.
источник
Все ответы копируют списки, или создают новый список, или используют медленные функции, или просто мучительно медленные.
Насколько я понимаю, это самый быстрый и самый дешевый метод, который я знаю (при поддержке очень опытного программиста, специализирующегося на оптимизации физики в реальном времени).
Окончательная стоимость:
nlogn + n + nlogn = n + 2nlogn = O (nlogn), что довольно приятно.
Примечание об RemoveRange: поскольку мы не можем установить счетчик списка и избежать использования функций удаления, я не знаю точно скорость этой операции, но я думаю, что это самый быстрый способ.
источник
Если у вас есть классы буксирных
Product
иCustomer
мы хотим , чтобы удалить повторяющиеся элементы из своего спискаВы должны определить общий класс в форме ниже
Затем вы можете удалить дубликаты в вашем списке.
этот код удалить повторяющиеся элементы по ,
Id
если вы хотите удалить повторяющиеся элементы от другого имущества, вы можете изменить тоnameof(YourClass.DuplicateProperty)
жеnameof(Customer.CustomerName)
затем удалить повторяющиеся элементы поCustomerName
недвижимости.источник
источник
Простая интуитивно понятная реализация:
источник