所以我理解如何使用来自Linq的Distinct()
来删除列表和int等列表中的重复项。但是,如何根据对象的特定属性删除重复项?
例如,我有一个TimeMetric
课程。此TimeMetric
类有两个属性:MetricText
和MetricTime
。我有TimeMetrics
名为MetricList
的列表。我想删除具有相同TimeMetric
属性的所有重复项MetricText
。 TimeMetric
值可以相同,但如果TimeMetric
具有相同的MetricText
,则必须将其重复。
答案 0 :(得分:21)
您需要使用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
)。如果0
为GetHashCode
,您应该这样做并从MetricText
返回null
。另一方面,如果MetricText
的类型是值类型,则无需执行任何修改。
然后:
var list = new List<TimeMetric> { ... };
var unique = list.Distinct(new MyComparer());
答案 1 :(得分:14)
使用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());
答案 2 :(得分:3)
您可以将Distinct overload与IEqualityComparer一起使用。
IEqualityComparer实现的equals方法如下所示:
bool Equals(TimeMetric x, TimeMetric y)
{
return x.MetricText.Equals(y.MetricText);
}