Sorting arrays

J

Jon Slaughter

public class PointSorter : IComparer<PointF>
{
int IComparer<PointF>.Compare(PointF x, PointF y)
{
if (x.X > y.X)
return 1;
if (x.X < y.X)
return -1;
return 0;
}

} IComparer<PointF> pointSorter = new PointSorter();


..... Later...

Array.Sort<PointF>(data, pointSorter);


So this code lets me sort a point array based on the x values. Is there any
way to shorten this code? I realize that its pretty short as is but seems
like way to much overkill just to do a simple sort on a "compound" object.
What would be nice is some anonymous comparators ;)

I'm also not sure if generics are needed here or not but the code works and
thats what I did.

Thanks,
Jon
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Jon said:
public class PointSorter : IComparer<PointF>
{
int IComparer<PointF>.Compare(PointF x, PointF y)
{
if (x.X > y.X)
return 1;
if (x.X < y.X)
return -1;
return 0;
}

} IComparer<PointF> pointSorter = new PointSorter();


.... Later...

Array.Sort<PointF>(data, pointSorter);


So this code lets me sort a point array based on the x values. Is there any
way to shorten this code? I realize that its pretty short as is but seems
like way to much overkill just to do a simple sort on a "compound" object.
What would be nice is some anonymous comparators ;)

You can use anonymous methods in 2.0+, see example below.

Arne

====================================

using System;
using System.Collections;

namespace E
{
public class MyData
{
private int v;
private string s;
public MyData() : this(0, "")
{
}
public MyData(int v, string s)
{
this.v = v;
this.s = s;
}
public int V
{
get
{
return v;
}
set
{
v = value;
}
}
public string S
{
get
{
return s;
}
set
{
s = value;
}
}
public override string ToString()
{
return ("(" + v + "," + s + ")");
}
}
public class MyDataComparer : IComparer
{
int IComparer.Compare(object o1, object o2) {
return (((MyData)o1).V - ((MyData)o2).V);
}
}
public class Program
{
public static void Main(string[] args)
{
MyData[] mda = new MyData[3];
mda[0] = new MyData(3, "BB");
mda[1] = new MyData(1, "A");
mda[2] = new MyData(2, "CCC");
foreach(MyData md in mda)
{
Console.WriteLine(md);
}
Console.WriteLine("Ascendeing sort 1.x style");
Array.Sort(mda, new MyDataComparer());
foreach(MyData md in mda)
{
Console.WriteLine(md);
}
Console.WriteLine("Decending sort 2.0+ style");
Array.Sort<MyData>(mda, delegate(MyData md1, MyData md2) { return
(md2.V - md1.V); } );
foreach(MyData md in mda)
{
Console.WriteLine(md);
}
Console.ReadKey(true);
}
}
}
 
M

Morten Wennevik [C# MVP]

Hi Jon,

Implementing what Arne told with additional sorting for Y of X coordinates are equal quickly leads to a messy line

Array.Sort<PointF>(data, delegate(PointF x, PointF y) { if (x.X == y.X) return x.Y.CompareTo(y.Y); else return x.X.CompareTo(y.X); });

Having the same in a comparer class is in my opinion better as the readability would increase.


Array.Sort<PointF>(data, new PointSorter());

....

public class PointSorter : IComparer<PointF>
{
int IComparer<PointF>.Compare(PointF x, PointF y)
{
if (x.X == y.X)
return x.Y.CompareTo(y.Y);
else
return x.X.CompareTo(y.X);
}
}

As for the Generics. You don't need it, but you also don't have to testthe objects that are being compared if you specify its type to begin with

public class PointSorter : System.Collections.IComparer
{
int System.Collections.IComparer.Compare(object x, object y)
{
if (x is PointF && y is PointF)
{
PointF px = (PointF)x;
PointF py = (PointF)y;

if (px.X == py.X)
return py.Y.CompareTo(py.Y);
else
return px.X.CompareTo(py.X);
}
else
{
return x.ToString().CompareTo(y.ToString());
}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top