删除列表中的重复对象(C#)
问题描述:
所以我知道如何通过使用Linq中的Distinct()
来删除列表中的重复项,以及字符串和整型等。但是,如何根据对象的特定属性删除重复项?删除列表中的重复对象(C#)
例如,我有一个TimeMetric
类。这个TimeMetric
类有两个属性:MetricText
和MetricTime
。我有一个TimeMetrics
名为MetricList
的清单。我想删除具有相同MetricText
属性的任何重复项TimeMetric
。 TimeMetric
的值可以相同,但如果有任何TimeMetric
具有相同的MetricText
,它必须是不重复的。
答
您需要使用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
)。如果MetricText
为null
,则应该这样做并从GetHashCode
返回0
。另一方面,如果MetricText
的类型是值类型,则不需要执行任何修改。
然后:
var list = new List<TimeMetric> { ... };
var unique = list.Distinct(new MyComparer());
答
可以使用Distinct overload与IEqualityComparer。
你对于自己的IEqualityComparer实现equals方法是这样的:
bool Equals(TimeMetric x, TimeMetric y)
{
return x.MetricText.Equals(y.MetricText);
}
答
使用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());
这是不正确的,并且只会在MetricText的类型为'string'(或者覆盖'operator ==' )。应该使用“Equals”。 – Jon
我认为这是一个字符串,这不是一个好的假设,并更新了回应。 –