3

* 解決済み - 下部のチケットが更新されました *

それぞれ「StartPoint」と「EndPoint」プロパティを持つ「line」オブジェクトのリストがあります。これらのプロパティには、それぞれ「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" 値で並べ替えられます。

では、一致を強制するより良い方法は何ですか? 独自の比較子を作成しますか?

4

1 に答える 1

0

更新された質問に答えます:

実際の値を変更せずに、丸められた値に基づいて注文とのカスタム比較を実行する場合は、 を実装できますIComparer<T>。次に、IComparer を受け取るオーバーロードを使用します。OrderBy<T>

public class NonExactLineComparer : IComparer<Line>
{
    public int Compare(Line x, Line y)
    {
        // Comparison logic
    }
}
于 2013-10-09T21:49:44.100 に答える