C# - 将参数作为输入的自定义IComparer <t>

时间:2017-01-29 10:37:35

标签: c# icomparer

我有一个点(x,y)列表,我想根据它们相对于参考点的极角进行排序,我将其计算为列表中所有点的平均点。 如何设置IComparer以便我可以将参考点传递给它来计算极角?

2 个答案:

答案 0 :(得分:3)

您可以提前计算参考点并将其传递给IComparer的构造函数:

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
    }
}

用法:

var ordered = myList.OrderBy(x => x, new PointComparer(calculatedReferencePoint));

我使用了OrderyBy而不是Sort,因为当我们参考文档时后者被认为不是稳定的排序。

答案 1 :(得分:1)

您有两种选择。

选项A

参考点必须是Point对象的一部分。因此,在Point的比较方法中,您可以考虑计算角度并比较对象。

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);