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
Post a Comment