使用的IComparer排序(Using IComparer for sorting)

2019-07-18 06:14发布

我想使用IComparer排序点的列表。 这里是的IComparer类:

public class CoordinatesBasedComparer : IComparer
{
    public int Compare(Object q, Object r)
    {
        Point a = (p)q;
        Point b = (p)r;
        if ((a.x == b.x) && (a.y == b.y))
            return 0;
        if ((a.x < b.x) || ((a.x == b.x) && (a.y < b.y)))
            return -1;

        return 1;
    }
}

在客户端代码,我试图使用这个类进行排序点p(类型的列表List<Point> ):

CoordinatesBasedComparer c = new CoordinatesBasedComparer();
Points.Sort(c);

代码中的错误了。 显然,它期待IComparer<Point>作为参数进行排序方法。
我需要做什么做解决这一问题?

Answer 1:

您需要实现强类型接口( MSDN )。

public class CoordinatesBasedComparer : IComparer<Point>
{
    public int Compare(Point a, Point b)
    {
        if ((a.x == b.x) && (a.y == b.y))
            return 0;
        if ((a.x < b.x) || ((a.x == b.x) && (a.y < b.y)))
            return -1;

        return 1;
    }
}

顺便说一句,我认为你使用太多的括号,我相信他们应该当他们的编译器贡献的前提下使用。 这是我的版本:

if (a.x == b.x && a.y == b.y)
    return 0;
if (a.x < b.x || (a.x == b.x && a.y < b.y))
    return -1;

就像我不喜欢用的人return (0)


请注意,如果您指定一个.net 3.5 +应用程序,您可以使用LINQ哪一个更容易,甚至与排序更快。

LINQ vesion可以是这样的:

var orderedList = Points.OrderBy(point => point.x)
                        .ThenBy(point => point.y)
                        .ToList();


Answer 2:

public class CoordinatesBasedComparer : IComparer, IComparer<Point>
{
    public int Compare(Point a, Point b)
    {
        if ((a.x == b.x) && (a.y == b.y))
            return 0;
        if ((a.x < b.x) || ((a.x == b.x) && (a.y < b.y)))
            return -1;

        return 1;
    }
    int IComparer.Compare(Object q, Object r)
    {
        return Compare((Point)q, (Point)r);            
    }
}


Answer 3:

如果你慢我一样,在-1和1可能很难理当使用约IComparer 。 想想它的方式是,当x应该先去,返回-1。 当y应该首先去,返回1。

它仍然可能会比较混乱,如果你有很多的字段作为排序依据。 您可以使用一个Enum ,让您比较逻辑比1和-1更具可读性,然后把结果。

本实施例中提出的对象与前空场的量最少。

public class NullishObjectsToTheBackOfTheLine: IComparer<ClassToCompare>
{
    private enum Xy
    {
        X = -1,
        Both = 0,
        Y = 1
    };

    //the IComparer implementation wraps your readable code in an int cast.
    public int Compare(ClassToCompare x, ClassToCompare y)
    {
        return (int) CompareXy(x, y);
    }

    private static Xy CompareXy(ClassToCompare x, ClassToCompare y)
    {
        if (x == null && y == null) return Xy.Both;

        //put any nulls at the end of the list
        if (x == null) return Xy.Y;
        if (y == null) return Xy.X;

        if (x.Country == y.Country && x.ProductId == y.ProductId) return Xy.Both;

        //put the least amount of at the front
        if (x.ProductId == null && x.Country == null) return Xy.Y;
        if (y.ProductId == null && y.Country == null) return Xy.X;

        //put the country values that are not nulls in front
        if (x.Country != y.Country) return x.Country != null ? Xy.X :  Xy.Y;

        //if we got this far, one of these has a null product id and the other doesn't
        return x.ProductId != null ? Xy.X : Xy.Y;
    }

}

public class ClassToCompare
{
    public string Country { get; set; }
    public string ProductId { get; set; }
}


Answer 4:

我正在一个InvalidOperation错误,同时添加类型的对象MyClass一个SortedList<MyClass> 。 当时的我,不正确,实现IComparer接口。 我需要实现IComparable接口是与方法的CompareTo(MyClass的除外),而不是ICompare.Compare(MyClass的X,MyClass的Y)。 这是一个简化的例子:

SortedList<MyClass> sortedList = new SortedList<MyClass>();
MyClass a=new MyClass(), b=new MyClass();
sortedList.Add(a);
sortedList.Add(b); // Note, sort only happens once second element is added

这个固定

public class MyClass : IComparable<MyClass>
{
    int IComparable<MyClass>.CompareTo(MyClass other)
    {
        // DoCompareFunction(this, other); and return -1,0,1
    }
}

此被破坏(不若加入做这个SortedList<MyClass> ):

public class MyClass : IComparer<MyClass>
{
    int IComparable<MyClass>.Compare(MyClass x, MyClass y)
    {
        // DoCompareFunction(x, y); and return -1,0,1
    }
}

这是错误:

无法比较阵列中的两个元素。
在System.Collections.Generic.ArraySortHelper`1.BinarySearch(T []数组,的Int32索引,长度的Int32,T值,比较器IComparer`1)
在System.Array.BinarySearch [T](T []数组,的Int32索引,长度的Int32,T值,比较器IComparer`1)
在System.Collections.Generic.SortedList`2.Add(TKEY的键,TValue值)



文章来源: Using IComparer for sorting