如何快速查找List <t>中的重复项,并更新原始集合</t>

时间:2009-04-27 05:29:35

标签: linq generics sorting

首先我要说的是我已经阅读了这些问题:1&amp; 2,我知道我可以编写代码来查找我的列表中的重复项,但我的问题是我想更新原始列表而不仅仅是查询并打印重复项。

我知道我无法更新查询返回的集合,因为它不是一个视图,它是一个匿名类型IEnumerable<T>

我希望能够在列表中找到重复项,并标记我创建的名为State的属性,该属性稍后会在应用程序中使用。

有没有人遇到过这个问题,你能指出我正确的方向吗?

P.S。我正在使用ATM的方法是一个冒泡排序类型循环,逐项遍历列表并比较关键字段。显然这不是最快的方法。

编辑:

为了将列表中的项目视为“重复”,有三个必须匹配的字段。我们将它们称为Field1,Field2和Field3

我在基类上有一个重载的Equals()方法,用于比较这些字段。

我在MarkDuplicates()方法中跳过对象的唯一一次是对象状态是UNKNOWN还是ERROR,否则,我会测试它。

如果您需要更多详细信息,请与我们联系。

再次感谢!

3 个答案:

答案 0 :(得分:8)

我认为最简单的方法是首先编写一个扩展方法,在对象列表中找到重复项。由于您的对象使用.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 :(得分:1)

您的对象具有某种状态属性。您可能会根据其他属性或属性集找到重复项。为什么不:

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)
}

答案 2 :(得分:1)

IEnumerable<T> oldList;
IEnumerable<T> list;

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

编辑:我需要lrn2read。此代码适用于2个列表。我的坏。