C# Linq-按多个包含的属性对对象进行排序
*已解决-票证在底部更新* 我有一个“line”对象列表,每个对象都有一个“StartPoint”和一个“EndPoint”属性。这些特性包含标准的点对象,每个点对象都有一个“X”、“Y”和“Z”分量 使用Linq,我试图通过提升任一端点的最小Y值,然后提升任一端点的最小X值(当Y值匹配时),对列表进行排序 我认为以下方法可行:C# Linq-按多个包含的属性对对象进行排序,c#,linq,sorting,C#,Linq,Sorting,*已解决-票证在底部更新* 我有一个“line”对象列表,每个对象都有一个“StartPoint”和一个“EndPoint”属性。这些特性包含标准的点对象,每个点对象都有一个“X”、“Y”和“Z”分量 使用Linq,我试图通过提升任一端点的最小Y值,然后提升任一端点的最小X值(当Y值匹配时),对列表进行排序 我认为以下方法可行: var sortedList = linesList .OrderBy(o => Math.Min(o.StartPoint.Y, o.EndPoint.
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):
如您所见,“Y”值正确地升序,但“X”值却在降序
*更新**
在评论部分,提出了OrderBy比较器中存在典型浮点公差问题的可能性。作为快速测试,我将.OrderBy子句更改为:
.OrderBy(o=>Math.Min(Math.Round(o.StartPoint.Y,3),Math.Round(o.EndPoint.Y,3)))
虽然很难看,但它解决了排序问题。显然,没有一个“Y”值被认为是相等的。现在我已经强迫他们四舍五入到3个位置,这些值确实匹配,然后执行ThenBy子句以按“X”值排序
现在,有什么更好的方法来迫使比赛?编写我自己的比较器?我将回答更新后的问题: 如果要基于舍入值对订单执行自定义比较,而不修改实际值,则可以实现。然后使用需要IComparer的
public class NonExactLineComparer : IComparer<Line>
{
public int Compare(Line x, Line y)
{
// Comparison logic
}
}
公共类非精确线性比较器:IComparer
{
公共整数比较(x行,y行)
{
//比较逻辑
}
}
您能用一个简短但完整的程序来展示这一点吗?您确定某个地方的X值中没有进行否定吗?请提供表示StartPoint和EndPoint属性类型的类的名称和来源。是你写的,互联网上的某个家伙还是微软写的?如果您有源代码,请提供ToString方法并亲自查看。ToString方法是否遵守X、Y和Z的顺序?如果你没有资料来源,那么你有没有阅读过关于该类及其随从的图书馆文档?Jon,谢谢你的回答,但我不确定你在问什么(X值的否定)。除了在发布代码之前实际创建“line”对象列表之外,这就是手头的所有问题。我可以使用我发布的代码对列表进行排序并将其打印出来,并获得显示的结果。@JeffGodfrey您可以尝试在Line
类中使用decimal
来代替当前使用的类型吗?@Eduard-提供“Line”对象和“Point3D”的库对象是第三方商业CAD库。我没有这个案子的消息来源。虽然我相对确信Point3D.ToString()能够保持正确的X、Y、Z顺序,但我肯定会验证这一点。
public class NonExactLineComparer : IComparer<Line>
{
public int Compare(Line x, Line y)
{
// Comparison logic
}
}