[.net] IComparer

Started by
5 comments, last by SamLowry 14 years, 7 months ago
Hi, i´m using an IComparer to Sort my Pointlist. I want to sort it by increasing x and then increasing y-coordinates But it doesn´t work :(

public class PointComparer : IComparer
    {
        private bool coord;
        //
        public PointComparer(bool coord)
        {
            this.coord = coord;
        }
        //
        int IComparer.Compare(object a, object b)
        {
            var b1 = (Point)a;
            var b2 = (Point)b;
            if(coord)
            {
                if (b1.X < b2.X)
                    return -1;
                if (b1.X > b2.X)
                    return 1;
                return 0;
            }
            else
            {
                if (b1.X == b2.X)
                {
                    if (b1.Y < b2.Y)
                        return -1;
                    if (b1.Y > b2.Y)
                        return 1;
                    return 0;
                }
                return 0;
            }
        }
    }
//...
PVRTXList.Sort(new PointComparer(true)); // to sort by x
PVRTXList.Sort(new PointComparer(false)); // to sort the same x by y

Advertisement
You should perhaps try sorting using one comparer, instead of doing it in two steps, which is just awkward.

public class PointComparer : IComparer<Point>{    public int Compare(Point a, Point b)    {        if ( a.x < b.x ) return -1;        else if ( a.x > b.x ) return 1;        else return a.y - b.y;    }}

I haven't tested it, but it should work. I you really need a non-generic version, just add the necessary casts. Also, it might be safer to replace the last line by a couple of extra ifs, as you might have some overflow issues there.
Nope, this doesn´t work.


i also found out that i can sort with

Comparer.Default.Compare(b1.X, b2.X);

but this doesn´t really helps : /
public class App{    public static void Main( string[] args )    {        var pts = new List<Point>();        pts.Add( new Point( 1, 1 ) );        pts.Add( new Point( 2, 1 ) );        pts.Add( new Point( 1, 2 ) );        pts.Add( new Point( 2, 2 ) );        pts.Sort( new PointComparer() );        foreach ( var p in pts )        {            Console.WriteLine( p );        }                }}public class Point{    public Point( float x, float y )    {        this.X = x;        this.Y = y;    }    public float X { get; set; }    public float Y { get; set; }    public override string ToString()    {        return string.Format( "({0}, {1})", X, Y );    }}public class PointComparer : IComparer<Point>{    public int Compare( Point a, Point b )    {        var cx = a.X.CompareTo( b.X );        if ( cx != 0 )        {            return cx;        }        else        {            return a.Y.CompareTo( b.Y );        }    }}

Seems to work:
(1, 1)(1, 2)(2, 1)(2, 2)
Thanks, will try it.
Ok this works.

I thought i did the same in my code, strange : /
You're making the assumptions that the second sort knows it has to leave the "same X island" unperturbed, which I think is the case if the algorithm is stable (i.e. the relative position of equal elements must be preserved), but which it is not according to MSDN.

So, the algorithm you use probably just guarantees that a) the resulting list will be a permutation of the original one, and b) the elements will be ordered with respect to the predicate you provided. This means that the list {(1,2), (1,1), (2,2), (2,3), (3,3), (3,1)} can be sorted to many different "valid" lists according to your predicate (426 different possibilities if I'm not mistaken). My version of the predicate only allows for one correct solution.

This topic is closed to new replies.

Advertisement