Sorting an Array
-
I have spent a whole day trying to write a comarer and make sence out of MSDN's convoluted instructions but have not been able to get something that compiles and works.
public class Foo : Comparer<foo> { private string mMyString = new string('c', 100); public override int Compare(Foo one, Foo two) { return one.mMyString.Substring(59).CompareTo(two.mMyString.Substring(59)); } } Use System.Collections.Generic.List as the list. Also, you may have to vary the code in the Compare method as I did not bother to test it.
Need a C# Consultant? I'm available.
Happiness in intelligent people is the rarest thing I know. -- Ernest Hemingway -
I have spent a whole day trying to write a comarer and make sence out of MSDN's convoluted instructions but have not been able to get something that compiles and works.
A comparer is pretty simple. It's just a class with a Compare method that works like any other Compare method (like string.Compare for example). Try this:
class SubstringComparer : IComparer<string> {
private int _offset, _len;
public SubstringComparer(int offset, int len) { _offset = offset; _len = len; }
public override int Compare(string x, string y) {
return string.Compare(x, _offset, y, _offset, _len);
}
}Array.Sort(myArray, new SubstringComparer(59, int.MaxValue));
modified on Saturday, December 08, 2007 2:31:24 PM
-
A comparer is pretty simple. It's just a class with a Compare method that works like any other Compare method (like string.Compare for example). Try this:
class SubstringComparer : IComparer<string> {
private int _offset, _len;
public SubstringComparer(int offset, int len) { _offset = offset; _len = len; }
public override int Compare(string x, string y) {
return string.Compare(x, _offset, y, _offset, _len);
}
}Array.Sort(myArray, new SubstringComparer(59, int.MaxValue));
modified on Saturday, December 08, 2007 2:31:24 PM
This is my code that will not compile.
class SubstringComparer : IComparer<string> { private int _offset, _len; public SubstringComparer(int offset, int len) { _offset = offset; _len = len; } public override int Compare(string x, string y) //--------------------------------------------------------- // I get no suitable method found to override Compare //--------------------------------------------------------- { return string.Compare(x, _offset, y, _offset, _len); } } private void button13_Click(object sender, EventArgs e) { ArrayList arraylist = new ArrayList(); for (int i = 0; i < listBox1.Items.Count; i++) { string temp = listBox1.Items[i].ToString(); if (temp.Length>65) { arraylist.Add(temp); } } Array.Sort(arraylist, new SubstringComparer(59, int.MaxValue)); listBox1.Items.Clear(); for (int i = 0; i < arraylist.Count; i++) listBox1.Items.Add(arraylist[i]); } }
TNX for the helpmodified on Saturday, December 08, 2007 10:45:32 AM
-
This is my code that will not compile.
class SubstringComparer : IComparer<string> { private int _offset, _len; public SubstringComparer(int offset, int len) { _offset = offset; _len = len; } public override int Compare(string x, string y) //--------------------------------------------------------- // I get no suitable method found to override Compare //--------------------------------------------------------- { return string.Compare(x, _offset, y, _offset, _len); } } private void button13_Click(object sender, EventArgs e) { ArrayList arraylist = new ArrayList(); for (int i = 0; i < listBox1.Items.Count; i++) { string temp = listBox1.Items[i].ToString(); if (temp.Length>65) { arraylist.Add(temp); } } Array.Sort(arraylist, new SubstringComparer(59, int.MaxValue)); listBox1.Items.Clear(); for (int i = 0; i < arraylist.Count; i++) listBox1.Items.Add(arraylist[i]); } }
TNX for the helpmodified on Saturday, December 08, 2007 10:45:32 AM
Hi George, there are basically two ways (old and new): 1. if you want to sort an ArrayList in a special way, you need to create an object that implements
IComparer
(without < string> ) and knows how to compare two items. Its signature MUST bepublic int Compare(object obj1, object obj2)
There is no override, by writing ": Icomparer" you promise to implement the formentioned method. And you need to cast the arguments to strings explicitly, as in:string str1=(string)obj1
2. Starting with .NET 2.0 you can also use generic collections. The code Guffa showed you is fine if you keep the strings in a generic list, that is aList< string>
. In that case you inherit fromIComparer< string>
and your Compare method takes string arguments directly, but still there is nooverride
involved. The generics stuff basically makes all the castings redundant. Regards,Luc Pattyn [Forum Guidelines] [My Articles]
Sorry for any delays in replying, I currently don't get e-mail notifications.
-
This is my code that will not compile.
class SubstringComparer : IComparer<string> { private int _offset, _len; public SubstringComparer(int offset, int len) { _offset = offset; _len = len; } public override int Compare(string x, string y) //--------------------------------------------------------- // I get no suitable method found to override Compare //--------------------------------------------------------- { return string.Compare(x, _offset, y, _offset, _len); } } private void button13_Click(object sender, EventArgs e) { ArrayList arraylist = new ArrayList(); for (int i = 0; i < listBox1.Items.Count; i++) { string temp = listBox1.Items[i].ToString(); if (temp.Length>65) { arraylist.Add(temp); } } Array.Sort(arraylist, new SubstringComparer(59, int.MaxValue)); listBox1.Items.Clear(); for (int i = 0; i < arraylist.Count; i++) listBox1.Items.Add(arraylist[i]); } }
TNX for the helpmodified on Saturday, December 08, 2007 10:45:32 AM
Oh, you are not using an array at all, but an ArrayList. That's a big difference. Then you need a comparer that handles objects: class SubstringComparer : IComparer { private int _offset, _len; public SubstringComparer(int offset, int len) { _offset = offset; _len = len; } public override int Compare(object x, object y) { return string.Compare((string)x, _offset, (string)y, _offset, _len); } } And use it like this: arraylist.Sort(new SubstringComparer(59, int.MaxValue));
Experience is the sum of all the mistakes you have done.
-
Oh, you are not using an array at all, but an ArrayList. That's a big difference. Then you need a comparer that handles objects: class SubstringComparer : IComparer { private int _offset, _len; public SubstringComparer(int offset, int len) { _offset = offset; _len = len; } public override int Compare(object x, object y) { return string.Compare((string)x, _offset, (string)y, _offset, _len); } } And use it like this: arraylist.Sort(new SubstringComparer(59, int.MaxValue));
Experience is the sum of all the mistakes you have done.
Still will not compile
class SubstringComparer : IComparer { private int \_offset, \_len; public SubstringComparer(int offset, int len) { \_offset = offset; \_len = len; } public override int Compare(object x, object y) //----------------------------------------------------------------------- // On Compare I still get no suitable method to overide // //----------------------------------------------------------------------- { return string.Compare((string)x, \_offset, (string)y, \_offset, \_len); } } private void button13\_Click(object sender, EventArgs e) { ArrayList arraylist = new ArrayList(); for (int i = 0; i < listBox1.Items.Count; i++) { string temp = listBox1.Items\[i\].ToString(); if (temp.Length>65) { arraylist.Add(temp); } } arraylist.Sort(new SubstringComparer(59, int.MaxValue)); listBox1.Items.Clear(); for (int i = 0; i < arraylist.Count; i++) listBox1.Items.Add(arraylist\[i\]); }
-
Hi George, there are basically two ways (old and new): 1. if you want to sort an ArrayList in a special way, you need to create an object that implements
IComparer
(without < string> ) and knows how to compare two items. Its signature MUST bepublic int Compare(object obj1, object obj2)
There is no override, by writing ": Icomparer" you promise to implement the formentioned method. And you need to cast the arguments to strings explicitly, as in:string str1=(string)obj1
2. Starting with .NET 2.0 you can also use generic collections. The code Guffa showed you is fine if you keep the strings in a generic list, that is aList< string>
. In that case you inherit fromIComparer< string>
and your Compare method takes string arguments directly, but still there is nooverride
involved. The generics stuff basically makes all the castings redundant. Regards,Luc Pattyn [Forum Guidelines] [My Articles]
Sorry for any delays in replying, I currently don't get e-mail notifications.
-
Still will not compile
class SubstringComparer : IComparer { private int \_offset, \_len; public SubstringComparer(int offset, int len) { \_offset = offset; \_len = len; } public override int Compare(object x, object y) //----------------------------------------------------------------------- // On Compare I still get no suitable method to overide // //----------------------------------------------------------------------- { return string.Compare((string)x, \_offset, (string)y, \_offset, \_len); } } private void button13\_Click(object sender, EventArgs e) { ArrayList arraylist = new ArrayList(); for (int i = 0; i < listBox1.Items.Count; i++) { string temp = listBox1.Items\[i\].ToString(); if (temp.Length>65) { arraylist.Add(temp); } } arraylist.Sort(new SubstringComparer(59, int.MaxValue)); listBox1.Items.Clear(); for (int i = 0; i < arraylist.Count; i++) listBox1.Items.Add(arraylist\[i\]); }
-
Is it possible that my problem is associated with the fact that I am using .NET 3.5 and Visual 2008.
Hi George, I don't know for sure about 3.5/2008 since I haven't used them yet. but there are some problems in the code you posted, as I pointed out before. For one you should drop the "override" then choose either an ArrayList (1. in my earlier reply) or List< string> (2) and make your Compare accordingly. :)
Luc Pattyn [Forum Guidelines] [My Articles]
Sorry for any delays in replying, I currently don't get e-mail notifications.
-
Is it possible that my problem is associated with the fact that I am using .NET 3.5 and Visual 2008.
I haven't investigated to see if there are any new 'features' in this regard - but Generic Lists, IComparer and IComparable definately function as before and none of the 'normal' methods have changed in VS2008/.NET3.5 To be honest, so far I've had no problems coding exactly the same as I did with 2005 with all classes/interfaces etc.
-
Silly me... It's an interface, so you don't override the methods. Just remove the override keyword.
Experience is the sum of all the mistakes you have done.
modified on Monday, December 10, 2007 7:05:57 PM
-
I haven't investigated to see if there are any new 'features' in this regard - but Generic Lists, IComparer and IComparable definately function as before and none of the 'normal' methods have changed in VS2008/.NET3.5 To be honest, so far I've had no problems coding exactly the same as I did with 2005 with all classes/interfaces etc.