したがって、LinqのDistinct()
を使用して、文字列やintなどに関してリスト内の重複を削除する方法を理解しています。しかし、オブジェクトの特定の属性に基づいて重複をどのように削除しますか?
たとえば、私はTimeMetric
クラスを持っています。このTimeMetric
クラスには、MetricText
とMetricTime
の2つの属性があります。 TimeMetrics
というMetricList
のリストがあります。同じTimeMetric
属性を持つ重複するMetricText
を削除したい。 TimeMetric
の値は同じでもかまいませんが、TimeMetric
のMetricText
が同じである場合は、複製を解除する必要があります。
IEqualityComparer<TimeMetric>
インスタンスを2番目のパラメーターとして受け取るDistinct
の2番目のオーバーロードを使用する必要があります。次のように比較子を定義します。
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
)なので、そうなる可能性があります。 GetHashCode
がMetricText
の場合は、それを実行してnull
から0
を返す必要があります。一方、MetricText
の型が値型の場合は、変更を加える必要はありません。
その後:
var list = new List<TimeMetric> { ... };
var unique = list.Distinct(new MyComparer());
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());
個別のオーバーロード を IEqualityComparer とともに使用できます。
IEqualityComparer実装のequalsメソッドは次のようになります。
bool Equals(TimeMetric x, TimeMetric y)
{
return x.MetricText.Equals(y.MetricText);
}