使用LINQ对C#中的列表进行排序

使用LINQ对C#中的列表进行排序,c#,linq,list,sorting,C#,Linq,List,Sorting,有一个由这些类定义的多边形列表list polygons 如何对该列表进行排序,使多边形首先按其点的X属性排序,然后按其点的Y属性按升序排序 public class Polygon { public List<Point2D> Points; } public class Point2D { public double X; public double Y; } 排序后的输出: (A) (0, -10) -> (5, -9) -> (5, -

有一个由这些类定义的多边形列表
list polygons

如何对该列表进行排序,使多边形首先按其点的X属性排序,然后按其点的Y属性按升序排序

public class Polygon
{
    public List<Point2D> Points;
}

public class Point2D
{
    public double X;
    public double Y;
}
排序后的输出:

(A) (0, -10) -> (5, -9) -> (5, -13) -> (0, -13) -> (0, -10)
(B) (0, 0) -> (5, 1) -> (5, -3) -> (0, -3) -> (0, 0)
(C) (10, 0) -> (15, 1) -> (15, -3) -> (10, -3) -> (10, 0)

您似乎希望基于多边形点的最小X值对多边形进行排序,如果这些值相等,则基于多边形点的最小Y值

以下是使用LINQ的方法:

var result =
    Polygons
    //Order by smallest X
    .OrderBy(pl => pl.Points.Min(pn => pn.X)) 
    //Then by smallest Y
    .ThenBy(pl => pl.Points.Min(pn => pn.Y))
    .ToList();

您需要向多边形类添加其他属性

public class Polygon
{
    public List<Point2D> Points;

    public Point2D MinPoint;
}
然后你就可以分类了

var sortedPolygons = polygons.OrderBy(p=>p.MinPoint.X).ThenBy(p=>p.MinPoint.Y);

可以编写一个比较器类来比较多边形内的点,并使用该类对多边形进行排序

class PointsComparer : IComparer<List<Point2D>>
{
    public int Compare(List<Point2D> left, List<Point2D> right)
    {
        for (int i = 0; i < left.Count && i < right.Count; i++) {
            int c = left[i].X.CompareTo(right[i].X);
            if (c != 0) return c;
            c = left[i].Y.CompareTo(right[i].Y);
            if (c != 0) return c;
        }
        return left.Count.CompareTo(right.Count);
    }
}


polygons.OrderBy(poly => poly.Points, new PointsComparer());
类点比较程序:IComparer
{
公共整数比较(左列表、右列表)
{
for(int i=0;ipoly.Points,newpointscomparer());

旁注:您可能希望将这些字段转换为属性。

如果多边形有交点怎么办?是什么使一个多边形位于另一个多边形之前?该多边形的最小X与另一个多边形的最小X?如果它们相等,那么比较polygon1的最小Y和polygon2的最小Y?为什么
(0,0)
小于
(0,-10)
?看看我的解决方案。应该这样做的特里奇不认为这是他所做的,因为否则多边形B会比多边形C更早结束(B和C是原始列表中的名称;OP似乎不会将它们保留在排序列表中)。看起来你也发现了这一点(我是指你对这个问题的评论)。这似乎是正确的答案。我在准备示例时犯了一个错误。但是整个想法是正确的。@dasblinkenlight,对于Y,我将其从
Min
更改为
Max
,以使其适用于提供的示例OP。如果OP搞错了,他可以把它从
Max
改回
Min
@YacoubMassad,我做了。谢谢我现在就来试试。你也可以把minpoint部分放在polygon类中,它自己也可以建议在Point2D中实现IComparable接口,你可以直接将两点的比较添加到方法中,并使用标准的排序机制。同样的情况也应适用于多边形。这实际上是“按书”的解决方案。Orderby需要IComparer,而不是IComparable
var sortedPolygons = polygons.OrderBy(p=>p.MinPoint.X).ThenBy(p=>p.MinPoint.Y);
class PointsComparer : IComparer<List<Point2D>>
{
    public int Compare(List<Point2D> left, List<Point2D> right)
    {
        for (int i = 0; i < left.Count && i < right.Count; i++) {
            int c = left[i].X.CompareTo(right[i].X);
            if (c != 0) return c;
            c = left[i].Y.CompareTo(right[i].Y);
            if (c != 0) return c;
        }
        return left.Count.CompareTo(right.Count);
    }
}


polygons.OrderBy(poly => poly.Points, new PointsComparer());