2016-05-20 9 views
0
class Program 
{ 
    static void Main(string[] args) 
    { 
     IEnumerable<View> views = new List<View> 
     { 
      new View() {CoordSys = new Plane(){Org=new Origin(){x=1,Vector=0}}, PartNums = new List<int> {1,2,3}} 
      ,new View() {CoordSys = new Plane(){Org=new Origin(){x=2,Vector=0}}, PartNums = new List<int> {4,5,6}} 
      ,new View() {CoordSys = new Plane(){Org=new Origin(){x=3,Vector=0}}, PartNums = new List<int> {13,14,15}} 
      ,new View() {CoordSys = new Plane(){Org=new Origin(){x=2,Vector=0}}, PartNums = new List<int> {7,8,9}} 
      ,new View() {CoordSys = new Plane(){Org=new Origin(){x=2,Vector=0}}, PartNums = new List<int> {10,11,12}} 
      ,new View() {CoordSys = new Plane(){Org=new Origin(){x=1,Vector=0}}, PartNums = new List<int> {16,17,18}} 
     }; 

     IEnumerable<View> viewsByGroup = views.GroupBy(v => v, new ViewComparer()); 

     // loop to process groups 

     Console.ReadLine(); 
    } 
} 

class ViewComparer : IEqualityComparer<View> 
{ 
    public bool Equals(View x, View y) 
    { 
     return x.CoordSys.Org.x == y.CoordSys.Org.x 
      && x.CoordSys.Org.Vector == y.CoordSys.Org.Vector; 
    } 

    public int GetHashCode(View obj) 
    { 
     return obj.CoordSys.GetHashCode(); 
    } 
} 

Wie schreibe ich den GroupBy Vergleicher? Ich möchte Gruppen, in denen CoordSys gleich ist. Dies ist mein erster Versuch, eine benutzerdefinierte groupBy zu schreiben. Dieser Beispielcode hat viele Ints in dem Versuch, es einfach zu machen. Die tatsächliche CoordSys ist komplexer.Wie schreibe ich benutzerdefinierte Linq groupBy

+0

Danke für diejenigen, die geantwortet haben, leider muss ich meinen Vergleicher schreiben, weil meine CoordSys-Eigenschaft viel komplexer ist als der Int, den ich in meinem Beispiel zeigte. Ich habe versucht, das Problem zu vereinfachen, das Sie in die Irre geführt haben könnte. Mein CoordSys besteht eigentlich aus einer Ebene, einem Ursprung und einem Vektor senkrecht zur Ebene. All dies muss in meiner endgültigen Vergleichslösung berücksichtigt werden. Danke – DustyB

Antwort

0

Der Zweck davon war, mir zu helfen, zu verstehen, wie man einen kundenspezifischen Vergleicher schreibt. Obwohl eine einfache GrouBy mein Beispiel gelöst hätte, verwendete die endgültige Lösung einige API-Aufrufe, die einen benutzerdefinierten Vergleich erforderten. Jedenfalls habe ich eine Probe, die jetzt funktioniert.

class Program 
{ 
    static void Main(string[] args) 
    { 
     IEnumerable<View> views = new List<View> 
     { 
      new View() {CoordSys = new Plane(){Origin=new Origin(){x=1,y=0},Vector=0}, PartNums = new List<int> {1,2,3}} 
      ,new View() {CoordSys = new Plane(){Origin=new Origin(){x=3,y=0},Vector=0}, PartNums = new List<int> {13,14,15}} 
      ,new View() {CoordSys = new Plane(){Origin=new Origin(){x=2,y=0},Vector=0}, PartNums = new List<int> {4,5,6}} 
      ,new View() {CoordSys = new Plane(){Origin=new Origin(){x=1,y=0},Vector=0}, PartNums = new List<int> {16,17,18}} 
      ,new View() {CoordSys = new Plane(){Origin=new Origin(){x=2,y=0},Vector=0}, PartNums = new List<int> {7,8,9}} 
      ,new View() {CoordSys = new Plane(){Origin=new Origin(){x=2,y=0},Vector=0}, PartNums = new List<int> {10,11,12}} 
     }; 

     var viewsByGroup = views.GroupBy(p => p, new ViewComparer()); 

     foreach (var group in viewsByGroup) 
     { 
      foreach (var numList in group.Select(p => p.PartNums)) 
       foreach (int num in numList) 
        Console.Write(num + ", "); 

      Console.WriteLine(); 
     } 

     Console.ReadLine(); 
    } 
} 

class ViewComparer : IEqualityComparer<View> 
{ 
    public bool Equals(View x, View y) 
    { 
     return x.CoordSys.Origin.x == y.CoordSys.Origin.x 
      && x.CoordSys.Vector == y.CoordSys.Vector; 
    } 

    public int GetHashCode(View obj) 
    { 
     return obj.CoordSys.Origin.x.GetHashCode() 
      ^obj.CoordSys.Vector.GetHashCode(); 
    } 
} 
1

versuchen, diese

var Group = views.GroupBy(v => v.CoordSys); 
3

Sie Gruppe können Ihre views wie diese

var groups = views.GroupBy(v => v.CoordSys); 

Sie Dies gibt ein IEnumerable<IGrouping<View>>. Sie können dies wie folgt verwenden, zB:

foreach(var group in groups) 
{ 
    Console.Write("CoordSys = " + group.Key + " "); 
    Console.Write("Elements: " + group.Count()); 
} 

Die IGrouping ist essentialy ein IEnumerable der View s in der Gruppe plus eine Key Eigenschaft den Wert, der Sie durch (CoordSys in Ihrem Fall) gruppiert.

+0

Genau wohin ich gehe außer meinem CoorSys in der Probe ist zu einfach und war als Ergebnis irreführend. – DustyB