c# - Create a dictionary from the common property values of a List<Object> -


let's have list of _2dline objects.

public class _2dline {     public double x1 { get; set; }     public double y1 { get; set; }     public double x2 { get; set; }     public double y2 { get; set; } }  var l1 = new _2dline { x1 = 0, y1 = 0, x2 = 100, y2 = 100 }; var l2 = new _2dline { x1 = 50, y1 = 50, x2 = 200, y2 = 200 }; var l3 = new _2dline { x1 = 0, y1 = 0, x2 = 200, y2 = 200}; var l4 = new _2dline { x1 = 100, y1 = 100, x2 = 50, y2 = 50};  var mylines = new list<_2dline> {     l1,     l2,     l3,     l4 } 

as can see, of lines have points in common. how can extract points list dictionary specific _2dpoint(x,y) have list of lines entering or exiting point.

var mypoints = new dictionary<_2dpoint, list<_2dline>>();  public class _2dpoint {     public double x { get; set; }     public double y { get; set; } } 

the final result this:

  key              |    value ----------------------------------- _2dpoint(0,0)      |   { l1, l3 } _2dpoint(100,100)  |   { l1, l4 } _2dpoint(50,50)    |   { l2, l4 } _2dpoint(200,200)  |   { l2, l3 } 

project lines flattened sequence of points , lines, group sequence points (i use anonymous types, because have implemented equals , gethashcode) , create dictionary:

var result = mylines.selectmany(l => new[] {                                     new { x = l.x1, y = l.y1 },                                    new { x = l.x2, y = l.y2 }                                 }, (l,p) => new { point = p, line = l })                    .groupby(x => x.point)                    .todictionary(g => new _2dpoint { x = g.key.x, y = g.key.y },                                  g => g.select(x => x.line).tolist()); 

suggestion - use points start , end of lines, instead having 4 coordinates. improve naming. don't start class names underscore, use camelcase names local variables. e.g.

public class line {     public line(double startx, double starty, double endx, double endy)         : this(new point(startx, starty), new point(endx, endy))     {     }      public line(point start, point end)     {         start = start;         end = end;     }     public point start { get; private set; }     public point end { get; private set; } } 

i create point value object , override equals , gethashcode methods compare points values:

public class point {     public point(double x, double y)     {         x = x;         y = y;     }     public double x { get; private set; }     public double y { get; private set; }      public override bool equals(object obj)     {         point other = obj point;         if (other == null)             return false;          return x == other.x && y == other.y;     }      public override int gethashcode()     {                     return x.gethashcode() * 19 + y.gethashcode();     } } 

now creating list of lines looks like:

var lines = new list<line> {     new line(0, 0, 100, 100),     new line(50, 50, 200, 200),     new line(0, 0, 200, 200),     new line(100, 100, 50, 50) }; 

and points dictionary creation:

var points = lines.selectmany(l => new[] { l.start, l.end },                               (l, p) => new { line = l, point = p })                   .groupby(x => x.point)                   .todictionary(g => g.key, g => g.select(x => x.line).tolist()); 

Comments

Popular posts from this blog

commonjs - How to write a typescript definition file for a node module that exports a function? -

openid - Okta: Failed to get authorization code through API call -

ios - Change Storyboard View using Seague -