C#列表 - 通过比较特定属性来消除重复项

3
List<ClassA> newlist;
List<ClassA> oldlist;

ClassA有20个不同的属性, 我想要:

  • 比较并从新列表中删除完全匹配的项
  • 但是比较必须排除ClassA中的一些属性,因为这些值不相关
  • 我正在处理的记录集非常庞大(30万到40万)。所以它必须高效。

Linq的ExceptIntersect似乎不支持上述要求,而且好像速度也很慢。 有什么建议可以实现这一点吗?


2
只需使用自定义比较器的 .Distinct。如果所有相关属性都匹配,则它们是相等的。将更快的类型比较放在前面(整数,布尔值等),慢一些的类型放在最后(字符串,复杂类型),因此在许多情况下,您会发现在采取重量级操作之前元素是不相等的。根据您的情况,最好实际上对每个对象的所有相关属性进行哈希处理,并在继续比较属性的实际值之前进行哈希比较(假设属性在任务期间不会更改值)。 - SimpleVar
3个回答

7
您可以实现自己的自定义比较器。
public class MyEqualityComparer: IEqualityComparer<ClassA> {
  public bool Equals(ClassA x, ClassA y) {
    if (Object.ReferenceEquals(x, y))
      return true;  
    else if ((null == x) || (null == y))
      return false;

    // Your custom comparison here (...has to exclude few properties from ClassA)  
    ... 
  }

  public int GetHashCode(ClassA obj) {
    if (null == obj)
      return 0;

    // Your custom hash code based on the included properties 
    ...
  }
}

如果我们想要排除oldlistnewlist中,并使用HashSet<ClassA>

HashSet<ClassA> toExclude = new HashSet<ClassA>(
   oldlist, 
   new MyEqualityComparer());

newList.RemoveAll(item => toExclude.Conytains(item));

谢谢您的提问:) 我有点困惑,当我调用MyEqualityComparer时,我不需要传递新列表吗? - KeenUser
@KeenUser:不是的,MyEqualityComparer 只是一个用于比较两个 ClassA 实例是否相等的 自定义规则 - Dmitry Bychenko
@Dmitry Bychenko 为什么不使用 HashSet 的 Except 方法呢? - CSharpie
@CSharpie:这个问题的标题是“C#列表-消除重复项...”,所以我放置了newList.RemoveAll(item => ...),如果newList可以表示为HashSet<ClassA>,那么Except将是一个很好的实现。 - Dmitry Bychenko
@KeenUser 这都与EqualityComparer有关。 - CSharpie
显示剩余9条评论

0

0
前段时间,我发现了以下函数,它允许您根据特定属性进行去重。
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
    HashSet<TKey> seenKeys = new HashSet<TKey>();
    foreach (TSource element in source)
        if (seenKeys.Add(keySelector(element)))
            yield return element;
}

我找不到这篇文章的作者,所以感谢这位匿名程序员!
希望这是你要找的内容。

我有点困惑,我如何在这里使用两个不同列表的特定属性? - KeenUser
你想要从列表中获取不同的对象,对吗? - user4189129
是的,以不同的方式,但我想要列表1中与列表2匹配的项。不需要列表2中不同的项。 - KeenUser
哦,对不起,我误解了。我看到Dmitry为您提供了正确的答案。 - user4189129

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接