2012-02-21 4 views
1

私はクラスのインスタンスのリストを持っています。各インスタンスには、IListプロパティとカスタムクラスのオブジェクトが含まれています。ここでは、このListにすべてのDistictインスタンスをドロップします。そこには、IList-Propertyを含む要素とMyMulti-ClassのMulti-Propertyが等しい要素があります。 Listの1つの要素だけ残したいと思います。ここでは、「someData」プロパティの「First」プロパティが最も低くなります。 リストの要素をIList-Propertyと "SomeData"プロパティの "Multi"プロパティでグループ化し、 "SomeData"プロパティの "First"プロパティで並べ替えることを提案しました。各グループの最初の要素を選択します。C#:リストを含むこととの区別

可能な限りパフォーマンスが必要です。誰にでもアイデアはありますか?

例:

class myClass 
{ 
    public IList<String> SomeStrings { get; set; } 
    public MyMulti SomeData { get; set; } 

    public myClass(MyMulti data, params string[] strings) 
    { 
     SomeData = data; 
     SomeStrings = strings; 
    } 
} 

class MyMulti 
{ 
    public int First { get; set; } 
    public int Second { get; set; } 

    public int Multi 
    { 
     get 
     { 
      return First * Second; 
     } 
    } 

    public MyMulti(int first, int second) 
    { 
     First = first; 
     Second = second; 
    } 
} 
var mc1 = new myClass(new MyMulti(6, 4), "0", "1"); 
var mc2 = new myClass(new MyMulti(3, 8), "0", "1"); 
var mc3 = new myClass(new MyMulti(7, 3), "0", "1"); 
var mc4 = new myClass(new MyMulti(2, 35), "0", "2"); 
var mc5 = new myClass(new MyMulti(5, 4), "1", "1"); 
var mc6 = new myClass(new MyMulti(7, 10), "0", "2"); 

IList<myClass> aList = new List<myClass>(){mc1, mc2, mc3, mc4, mc5, mc6}; 

var query = aList.GroupBy(x => 
    new 
    { 
     x.SomeData.Multi, 
     x.SomeStrings 
     // don't work cause this will compare the lists 
     // not the containing elements 
    }) 
    .Select(x=> 
     x.OrderBy(y=> 
      y.SomeData.First) 
      .First()); 

結果は次のようになりますMC1およびMC2は、グループ化され、その後、MC1ドロップ、グループ化された自身のグループ、MC4およびMC6をMC3、次いでMC6はdroped、自身のグループをMC5 - > MC2、 MC3、MC4、MC5は

EDITままにしてください:私が最初にMyClass.SomeData.First-プロパティでリストをソートしてからList.Distinct()を使用する場合

- 方法と​​カスタムIEqalityComparerのimplementiationを私は、私が探しているものを手に入れます。しかし、これはこれを行う最も効果的な方法ですか?

public class myClassEqualityComparer : IEqualityComparer<myClass> 
{ 

    public bool Equals(myClass x, myClass y) 
    { 
     if (!x.SomeData.Multi.Equals(y.SomeData.Multi)) 
      return false; 
     else 
      if (x.SomeStrings.AsEnumerable() 
        .SequenceEqual(y.SomeStrings.AsEnumerable())) 
       return true; 
     return false; 
    } 

    public int GetHashCode(myClass obj) 
    { 
     int hCode = obj.SomeData.Multi; 
     foreach (var item in obj.SomeStrings) 
     { 
      hCode = hCode^item.GetHashCode(); 
     } 
     return hCode.GetHashCode(); 
    } 
} 

答えて

1

は、なぜあなたは個別()メソッドを使用すると、機能がダウンして事を遅らせることがGetHashCodeメソッドあなたのWROK

List.Distinct();

+0

あなたの考えをありがとう。 IEqualityComparer の独自の実装を定義しようとしました。しかし、私は最低の "MyMulti.First"を選ぶことはできません、それはただの人を選びます。 – germanSharper

+0

IEqualityComparerの代わりにIComparable を実装します。 Phil

+0

IComparable をList.Distinct()と組み合わせる方法がわかりません。 List.Distinct()はEqualsとGetHashCodeを必要とし、IComparableはCompareToのみを提供します。私はこれが分別のためだと思った? – germanSharper

0

を行う可能性がありますしようといけません。 ハッシュコードはハッシュテーブルのバランスをとるために使用され、最高のパフォーマンスのために、ハッシュ関数はすべての入力に対してランダムな分布を生成する必要があります。試してみてください。

System.Diagnostics.Stopwatchを使用してパフォーマンスをテストし、100000から1000000回ループすることができます。

+0

ありがとうございます。そうです、これは約2%速いです。 – germanSharper

+0

大きな文字列と膨大な数の要素がある場合、実際に30%のパフォーマンス向上が得られます –

関連する問題