代码之家  ›  专栏  ›  技术社区  ›  Icemanind

如何使用LINQ查找和删除集合中的重复对象?

  •  7
  • Icemanind  · 技术社区  · 15 年前

    我有一个表示对象的简单类。它有5个属性(日期、2个小数、整数和字符串)。我有一个集合类,派生自 CollectionBase 它是一个容器类,用于保存第一个类中的多个对象。

    我的问题是,我想删除重复的对象(例如,具有相同日期、相同小数、相同整数和相同字符串的对象)。是否有可以写入的LINQ查询来查找和删除重复项?或者至少找到他们?

    2 回复  |  直到 12 年前
        1
  •  11
  •   LBushkin    15 年前

    您可以使用 Distinct 操作员。

    有两个重载-一个为您的类型使用默认的相等比较器(对于自定义类型,它将调用 Equals() 方法)。第二个允许您提供自己的相等比较器。它们都返回 新序列 表示原始集合,无重复项。 两个重载都不会实际修改初始集合-它们都会返回一个排除重复项的新序列。 .

    如果您只想查找重复项,可以使用 GroupBy 这样做:

    var groupsWithDups = list.GroupBy( x => new { A = x.A, B = x.B, ... }, x => x ) 
                             .Where( g => g.Count() > 1 );
    

    从类似于 IList<> 你可以这样做:

    yourList.RemoveAll( yourList.Except( yourList.Distinct() ) );
    
        2
  •  4
  •   JaredPar    15 年前

    如果简单类使用 Equals 以满足您的需求的方式,然后您可以使用不同的方法

    var col = ...;
    var noDupes = col.Distinct();
    

    如果没有,则需要提供 IEqualityComparer<T> 它以你想要的方式比较价值。例如(为简洁而忽略了空问题)

    public class MyTypeComparer : IEqualityComparer<MyType> {
      public bool Equals(MyType left, MyType right) {
        return left.Name == right.Name;
      }
      public int GetHashCode(MyType type) {
        return 42;
      }
    }
    
    var noDupes = col.Distinct(new MyTypeComparer());
    

    注意常量的用法 GetHashCode 是故意的。不知道关于 MyType 写一个有效和正确的散列函数是不可能的。我使用了一个不管类型的语义如何都正确的常量来代替有效的哈希函数。