2012-02-21 7 views
1

我有一個類的實例的列表。每個實例都包含一個IList屬性和一個自定義類的對象。現在我想刪除此列表中的所有distict實例,其中包含IList屬性和MyMulti-Class的多屬性的元素是相等的。我想只保留List中的一個元素,其中「someData」屬性的「First」屬性是最低的。 我的建議是,對組列表由含IList中,房產和其他元件「SomeData」 -property的「多」 - 屬性,並在排序由「SomeData」的「第一」 - 屬性,物業並選擇每個組的第一個元素。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,MC3自己的組,MC4和MC6分組,然後MC6 DROP掉,MC5自己的組 - > MC2, MC3,MC4,MC5應保持

編輯:

如果我第一次排序的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

你爲什麼不嘗試鮮明的()方法可以做你的WROK

List.Distinct();

+0

感謝您的寶貴意見。我試着去定義我自己的IEqualityComparer實現,其中包括。但在那裏,我無法選擇最低的「MyMulti.First」,它只挑選任何人。 – germanSharper 2012-02-21 10:11:22

+0

執行IComparable 而不是IEqualityComparer Phil 2012-02-21 10:25:34

+0

我不明白如何將IComparable 與List.Distinct()相結合。 List.Distinct()需要Equals和GetHashCode,IComparable只提供CompareTo。我認爲這只是爲了排序? – germanSharper 2012-02-21 11:08:21

0

你GetHashCode的功能可能會減緩物降。 散列碼用於平衡散列表,爲獲得最佳性能,散列函數必須爲所有輸入生成一個隨機分佈。您應該嘗試:

public int GetHashCode(myClass obj) 
{ 
    return obj.SomeData.First^obj.SomeData.Second; 
} 

您可以使用System.Diagnostics.Stopwatch測試性能,並循環100000到1000000次。

+0

謝謝。你說得對,這個速度快2%左右。 – germanSharper 2012-02-21 11:21:17

+0

事實上,如果你有大的字符串數組和大量的元素,你可以獲得高達30%的性能增益 – 2012-02-21 12:16:18