簡體   English   中英

從列表的公共屬性值創建字典<Object>

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM