删除列表中的重复对象 (C#)

Posted

技术标签:

【中文标题】删除列表中的重复对象 (C#)【英文标题】:Removing duplicate objects in a list (C#) 【发布时间】:2012-01-09 00:28:13 【问题描述】:

所以我了解如何使用 Linq 中的 Distinct() 删除列表中的字符串和 int 等重复项。但是如何根据对象的特定属性删除重复项呢?

例如,我有一个TimeMetric 类。这个TimeMetric 类有两个属性:MetricTextMetricTime。我有一个名为MetricListTimeMetrics 列表。我想删除具有相同MetricText 属性的所有重复项TimeMetricTimeMetric 值可以相同,但如果任何TimeMetric 具有相同的MetricText,则它必须是不重复的。

【问题讨论】:

【参考方案1】:

您需要使用Distinct 的第二个重载,它将IEqualityComparer<TimeMetric> 实例作为第二个参数。像这样定义一个比较器:

class MyComparer : IEqualityComparer<TimeMetric>

    public bool Equals(TimeMetric x, TimeMetric y)
    
        return x.MetricText.Equals(y.MetricText);
    

    public int GetHashCode(TimeMetric obj)
    
        return obj.MetricText.GetHashCode();
    

重要提示: 上面的代码没有检查MetricText 属性为null 的情况(听起来可能是,因为它很可能是string) .如果MetricTextnull,您应该这样做并从GetHashCode 返回0。另一方面,如果MetricText的类型是值类型,则不需要进行任何修改。

然后:

var list = new List<TimeMetric>  ... ;
var unique = list.Distinct(new MyComparer());

【讨论】:

【参考方案2】:

使用 linq:

var list = list 
    .GroupBy(i => i.MetricText)
    .Select(g => g.First())
    .ToList();

或者传入一个使用该属性的比较器:

public class mtCompare : IEqualityComparer<TimeMetric>

  public bool Equals(TimeMetric x, TimeMetric y)
  
    return Equals(x.MetricText, y.MetricText);
  

  public int GetHashCode(TimeMetric obj)
  
    return obj.MetricText.GetHashCode();
  


....

list.Distinct(new mtCompare());

【讨论】:

【参考方案3】:

您可以将Distinct overload 与IEqualityComparer 一起使用。

您的 IEqualityComparer 实现的 equals 方法如下所示:

bool Equals(TimeMetric x, TimeMetric y)

  return x.MetricText.Equals(y.MetricText);

【讨论】:

这是不正确的,只有当MetricText 的类型为string(或覆盖operator == 的其他类型)时才会正常工作。应该改用Equals 我假设它是一个字符串,这不是一个好的假设,并更新了响应。

以上是关于删除列表中的重复对象 (C#)的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python 删除对象列表中的重复项

如何在 C# 中删除(或取消)泛型数组列表中的对象? [复制]

list.remove(x) 删除超过此列表中的对象[重复]

从 C# 中的 List<T> 中删除重复项

在 C# 中的列表上使用 IEnumerable [重复]

从一个列表中删除元素如果不包含在另一个列表中。 C# [重复]