모든 점의 평균 점으로 계산 한 참조 점에 대한 극점 각도로 정렬하려는 점 (x, y) 목록이 있습니다. 목록에. polar angle 계산을 위해 참조 점을 전달할 수 있도록 IComparer를 어떻게 설정할 수 있습니까?C# - 사용자 정의 IComparer 입력으로 인수를받습니다.
0
A
답변
3
즉, 당신은 시간을 앞서 기준점을 계산할 수와 IComparer
의 생성자에 전달 : 나는 OrderyBy
을 사용
var ordered = myList.OrderBy(x => x, new PointComparer(calculatedReferencePoint));
:
class PointComparer : IComparer<Point>
{
private readonly Point referencePoint;
public PointComparer(Point referencePoint)
{
this.referencePoint = referencePoint;
}
public Int32 Compare(Point x, Point y)
{
// Compare using referencePoint
}
}
사용 후자는 죄수이기 때문에 Sort
이 아닙니다. 문서를 참조 할 때 안정적인 분류가 아닙니다.
1
두 가지 옵션이 있습니다.
옵션 A
기준점은 Point
개체의 일부 여야합니다. 따라서 Point
의 Compare 메서드에서 각도를 계산하고 개체를 비교하는 데 고려해야합니다.
public int IComparer.Compare(Point x, Point y) {
var angleX = Utilities.CalculateAngle(x.ReferencePoint);
var angleY = Utilities.CalculateAngle(y.ReferencePoint);
if (angleX < angleY) return -1;
if (angleX == angleY) return 0;
if (angleX > angleY) return 1;
// Or simply "return angleX - angleY;"
}
옵션 B는
Angle
은 이미 점에서 계산되어야한다. Point
을 불변 구조로 만들고 구조의 인스턴스 생성시 각도를 계산하십시오. 그러면 그 속성은 OrderBy
입니다.
public struct Point
{
public double Angle { get; private set; }
public Point(double referencePoint, double x, double y)
{
// TODO: Calculate Angle
}
}
points.OrderBy(p => p.Angle);
정확히 내가 뭘 찾고 있었는지, 고마워! –
또한 _class_ 유형'Comparer'에서 파생 될 수 있습니다. 'Compare (Point, Point)'메소드 (이번에는 기본 클래스에서 상속받은'abstract' 메소드의'override')가 필요 하겠지만, 장점은'IComparer '와 오래된 비 제너럴 IComparer. –
'OrderBy'를 사용할 때, 커스텀 클래스를 건너 뛰어'Comparison'델리게이트 (lambda)에서 그 참조 점을 캡쳐 (닫기) 할 수 있습니다. 그것은 myList.OrderBy (x =>/* 표현식 x와 calculatedReferencePoint * /)'일 것입니다. 비교자를 정말로 필요로한다면'Comparer .Create (x =>/* expression with x and calculatedReferencePoint * /)'와 같이'Create'를 사용하여 얻을 수 있습니다. 다시 커스텀 클래스를 작성할 필요가 없습니다. –