假设我们有一个_2DLine
个对象的列表。
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
}
如您所见,有些线路有共同点。 如何将此列表中的所有点提取到字典中,以便对于特定的_2DPoint(X,Y)
,我们将列出进入或退出该点的行。
var MyPoints = new Dictionary<_2DPoint, List<_2DLine>>();
public class _2DPoint
{
public double X { get; set; }
public double Y { get; set; }
}
最终结果如下:
Key | Value
-----------------------------------
_2DPoint(0,0) | { L1, L3 }
_2DPoint(100,100) | { L1, L4 }
_2DPoint(50,50) | { L2, L4 }
_2DPoint(200,200) | { L2, L3 }
答案 0 :(得分:2)
将项目线分成扁平的点和线序列,然后逐点分组(我使用匿名类型,因为它们已经实现了Equals和GetHashCode)并创建了字典:
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());
建议 - 使用您的点作为行的起点和终点,而不是有四个坐标。还改进命名。不要从下划线开始类名,使用camelCase名称作为局部变量。 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; }
}
我还会将point创建为值对象并覆盖Equals和GetHashCode方法,以便按值对比点:
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 as Point;
if (other == null)
return false;
return X == other.X && Y == other.Y;
}
public override int GetHashCode()
{
return X.GetHashCode() * 19 + Y.GetHashCode();
}
}
现在创建行列表如下:
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)
};
点词典创作:
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());