首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用IComparer进行排序

使用IComparer进行排序
EN

Stack Overflow用户
提问于 2013-01-15 19:08:28
回答 4查看 103.4K关注 0票数 48

我正在尝试使用IComparer对点列表进行排序。下面是IComparer类:

代码语言:javascript
复制
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>)进行排序:

代码语言:javascript
复制
CoordinatesBasedComparer c = new CoordinatesBasedComparer();
Points.Sort(c);

代码错误输出。显然,它期望IComparer<Point>作为排序方法的参数。

我需要做些什么来解决这个问题?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-01-15 19:11:01

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

代码语言:javascript
复制
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;
    }
}

顺便说一句,我认为你使用了太多的花括号,我认为只有在它们对编译器有贡献的时候才应该使用它们。这是我的版本:

代码语言:javascript
复制
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版本可以是这样的:

代码语言:javascript
复制
var orderedList = Points.OrderBy(point => point.x)
                        .ThenBy(point => point.y)
                        .ToList();
票数 61
EN

Stack Overflow用户

发布于 2013-01-15 19:11:36

代码语言:javascript
复制
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);            
    }
}
票数 13
EN

Stack Overflow用户

发布于 2017-07-20 06:03:10

如果您像我一样慢,那么在使用IComparer时,很难理解-1和1。思考这个问题的方法是,当x应该首先执行时,返回-1。当y应该首先执行时,返回1。

如果您有很多字段可供排序,它仍然会让人感到困惑。您可以使用Enum使比较逻辑比1和-1更具可读性,然后转换结果。

此示例将具有最少空字段的对象放在最前面。

代码语言:javascript
复制
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; }
}
票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14336416

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档