Reputation: 185
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();
}
}
How do I write the groupBy comparer? I want groups where CoordSys is equal. This is my first attempt to write a custom groupBy. This sample code has a lot of ints in trying to make it simple. The actual CoordSys is more complex.
Upvotes: 0
Views: 104
Reputation: 185
The purpose of this was to help me understand how to write a custom comparer. Although a simple GrouBy would have solved my sample, the final solution utilized some API calls that required a custom comparer. Anyway I have a sample that now works.
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();
}
}
Upvotes: 0
Reputation: 43906
You can group your views
like this
var groups = views.GroupBy(v => v.CoordSys);
This gives you an IEnumerable<IGrouping<View>>
. You can use this for example like this:
foreach(var group in groups)
{
Console.Write("CoordSys = " + group.Key + " ");
Console.Write("Elements: " + group.Count());
}
The IGrouping
is essentialy an IEnumerable
of the View
s in the group plus a Key
property representing the value you grouped by (CoordSys
in your case).
Upvotes: 3