Как быстро найти дубликаты в Списке <T>и обновить оригинальную коллекцию - PullRequest
4 голосов
/ 27 апреля 2009

Позвольте мне начать с того, что я прочитал эти вопросы: 1 & 2 , и я понимаю, что могу написать код для поиска дубликатов в моем Списке, но моя проблема Я хочу обновить оригинальный список, а не просто запросить и распечатать дубликаты.

Я знаю, что не могу обновить коллекцию, возвращаемую запросом, поскольку это не представление, а анонимный тип IEnumerable<T>.

Я хочу иметь возможность найти дубликаты в моем списке и отметить созданное мной свойство с именем State, которое позже будет использовано в приложении.

Кто-нибудь сталкивался с этой проблемой, и можете ли вы указать мне правильное направление?

p.s. Подход, который я использую в ATM - это цикл типа пузырьковой сортировки, чтобы пройти список по элементам и сравнить ключевые поля. Очевидно, что это не самый быстрый метод.

EDIT:

Чтобы считать элемент в списке «дубликатом», есть три поля, которые должны совпадать. Мы назовем их Field1, Field2 и Field3

У меня есть перегруженный метод Equals () в базовом классе, который сравнивает эти поля.

Единственный раз, когда я пропускаю объект в моем методе MarkDuplicates(), это если состояние объекта равно UNKNOWN или ERROR, в противном случае я проверяю его.

Дайте мне знать, если вам нужно больше деталей.

Еще раз спасибо!

Ответы [ 3 ]

8 голосов
/ 27 апреля 2009

Я думаю, что проще всего начать с написания метода расширения, который находит дубликаты в списке объектов. Поскольку ваши объекты используют .Equals (), их можно сравнивать в большинстве общих коллекций.

public static IEnumerable<T> FindDuplicates<T>(this IEnumerable<T> enumerable) {
  var hashset = new HashSet<T>();
  foreach ( var cur in enumerable ) { 
    if ( !hashset.Add(cur) ) {
      yield return cur;
    }
  }
}

Теперь должно быть довольно легко обновить вашу коллекцию на дубликаты. Например

List<SomeType> list = GetTheList();
list
  .FindDuplicates()
  .ToList()
  .ForEach(x => x.State = "DUPLICATE");

Если в вашем коде уже определен метод расширения ForEach, вы можете избежать .ToList.

1 голос
/ 27 апреля 2009
IEnumerable<T> oldList;
IEnumerable<T> list;

foreach (var n in oldList.Intersect(list))
   n.State = "Duplicate";

Редактировать: мне нужно lrn2read. этот код для 2 списков. Мой плохой.

1 голос
/ 27 апреля 2009

Ваши объекты имеют какую-то государственную собственность. Вы, вероятно, находите дубликаты на основе другого свойства или набора свойств. Почему бы и нет:

List<obj> keys = new List<object>();

foreach (MyObject obj in myList)
{
    if (keys.Contains(obj.keyProperty))
        obj.state = "something indicating a duplicate here";
    else
        keys.add(obj.keyProperty)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...