[英]Create a dictionary from the common property values of a List<Object>
假設我們有一個_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 }
將線投影到點和線的序列平整,然后按點對序列進行分組(我使用匿名類型,因為它們已經實現了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名稱用作局部變量。 例如
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; }
}
我還將創建點作為值對象,並覆蓋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());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.