Linq - 按几个包含的属性对对象列表进行排序

时间:2013-10-09 21:03:30

标签: c# linq sorting

*已解决 - 故障单在底部更新*

我有一个“行”对象列表,每个对象都有一个“StartPoint”和一个“EndPoint”属性。这些属性包含标准点对象,每个对象都带有“X”,“Y”和“Z”组件。

使用Linq,我首先尝试通过提升任一端点的最小Y值,然后通过提升任一端点的最小X值(当Y值匹配时)来对列表进行排序。

我认为以下内容可行:

var sortedList = linesList
    .OrderBy(o => Math.Min(o.StartPoint.Y, o.EndPoint.Y))
    .ThenBy(o => Math.Min(o.StartPoint.X, o.EndPoint.X));

foreach (Line thisLine in sortedList)
{
    Console.WriteLine(thisLine.StartPoint + ", " + thisLine.EndPoint);
}

然而,这产生了这个顺序(写成xs,ys,zs,xe,ye,ze):

737.928, 825.293, 0, 737.928, 826.293, 0
737.616, 825.293, 0, 737.616, 826.293, 0
733.928, 825.293, 0, 733.928, 826.293, 0
733.616, 825.293, 0, 733.616, 826.293, 0
729.928, 825.293, 0, 729.928, 826.293, 0
729.616, 825.293, 0, 729.616, 826.293, 0
725.928, 825.293, 0, 725.928, 826.293, 0
725.616, 825.293, 0, 725.616, 826.293, 0
721.928, 825.293, 0, 721.928, 826.293, 0
721.616, 825.293, 0, 721.616, 826.293, 0
717.928, 825.293, 0, 717.928, 826.293, 0
717.616, 825.293, 0, 717.616, 826.293, 0
713.928, 825.293, 0, 713.928, 826.293, 0
713.616, 825.293, 0, 713.616, 826.293, 0
709.928, 825.293, 0, 709.928, 826.293, 0
709.616, 825.293, 0, 709.616, 826.293, 0
705.928, 825.293, 0, 705.928, 826.293, 0
705.616, 825.293, 0, 705.616, 826.293, 0
701.928, 825.293, 0, 701.928, 826.293, 0
701.616, 825.293, 0, 701.616, 826.293, 0
697.928, 825.293, 0, 697.928, 826.293, 0
697.616, 825.293, 0, 697.616, 826.293, 0
693.928, 825.293, 0, 693.928, 826.293, 0
693.616, 825.293, 0, 693.616, 826.293, 0
689.928, 825.293, 0, 689.928, 826.293, 0
689.616, 825.293, 0, 689.616, 826.293, 0
685.928, 825.293, 0, 685.928, 826.293, 0
685.616, 825.293, 0, 685.616, 826.293, 0
681.928, 825.293, 0, 681.928, 826.293, 0
681.616, 825.293, 0, 681.616, 826.293, 0
677.928, 825.293, 0, 677.928, 826.293, 0
677.616, 825.293, 0, 677.616, 826.293, 0
673.928, 825.293, 0, 673.928, 826.293, 0
673.616, 825.293, 0, 673.616, 826.293, 0
669.928, 825.293, 0, 669.928, 826.293, 0
669.616, 825.293, 0, 669.616, 826.293, 0
737.928, 826.481, 0, 737.928, 827.481, 0
737.616, 826.481, 0, 737.616, 827.481, 0
733.928, 826.481, 0, 733.928, 827.481, 0
733.616, 826.481, 0, 733.616, 827.481, 0
729.928, 826.481, 0, 729.928, 827.481, 0
729.616, 826.481, 0, 729.616, 827.481, 0
.
.
.

如您所见,“Y”值正在升序,但“X”值正在下降。

*更新**

在评论部分中,提出了OrderBy比较器中典型浮动容差问题的可能性。作为一个快速测试,我将.OrderBy子句更改为:

.OrderBy(o => Math.Min(Math.Round(o.StartPoint.Y,3),Math.Round(o.EndPoint.Y,3)))

这很难看,但它修复了排序问题。显然,没有一个“Y”值被视为平等。现在我已强制它们舍入到3个位置,值匹配,并执行ThenBy子句以按“X”值排序。

现在,强迫比赛的更好方法是什么?写我自己的比较器?

1 个答案:

答案 0 :(得分:0)

我会回答更新的问题:

如果要在不修改实际值的情况下根据舍入值执行自定义比较,则可以实现IComparer<T>。然后使用带有IComparer的overload of OrderBy<T>

public class NonExactLineComparer : IComparer<Line>
{
    public int Compare(Line x, Line y)
    {
        // Comparison logic
    }
}