2011-11-29 28 views
18

LinqのDistinct()を使用して、文字列やintなどのリストを削除する方法を理解しています。しかし、オブジェクトの特定の属性に基づいて重複をどのように削除しますか?リスト内の重複するオブジェクトを削除する(C#)

たとえば、私はTimeMetricクラスを持っています。このTimeMetricクラスには、MetricTextMetricTimeという2つの属性があります。私はMetricListと呼ばれるTimeMetricsのリストを持っています。同じMetricText属性の重複を削除したい。TimeMetricTimeMetricの値は同じでもかまいませんが、TimeMetricに同じMetricTextがある場合は、重複しないようにする必要があります。

答えて

21

Distinctの第2のオーバーロードを使用する必要があります。これは、IEqualityComparer<TimeMetric>インスタンスを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だから、それは、音)このような比較演算子を定義します。 MetricTextnullの場合、それを実行して0GetHashCodeから返す必要があります。一方、MetricTextのタイプが値タイプの場合は、変更を行う必要はありません。その後、

そして:

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

あなたはIEqualityComparerDistinct overloadを使用することができます。

あなたたIEqualityComparerの実装は次のようになりますのためのあなたのequalsメソッド:

bool Equals(TimeMetric x, TimeMetric y) 
{ 
    return x.MetricText.Equals(y.MetricText); 
} 
+1

これは、 'MetricText'型が' string'型(または 'operator =='をオーバーライドする別の型)の場合にのみ正しく動作します)。代わりに 'Equals'を使うべきです。 – Jon

+0

私はそれが良い仮定ではない文字列であると仮定し、応答を更新しました。 –

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()); 
関連する問題