I have array list of strings:
"1A", "12A", "12B", "6", "A", "5B", "B", "13"
.
If I do myList.Sort();
then I get:
"1A", "12A", "12B", "13", "5B", "6", "A", "B"
.
But what I need is first sort by numbers in front, then by letter:
"1A", "5B", "6", "12A", "12B", "13", "A", "B"
.
I could use
public class CustomComparer : IComparer
{
Comparer _comparer = new Comparer(System.Globalization.CultureInfo.CurrentCulture);
public int Compare(object x, object y)
{
// Convert string comparisons to int
return _comparer.Compare(Convert.ToInt32(x), Convert.ToInt32(y));
}
}
But it throws exception. How do I get what I need?
Your comparer is too simplistic. Your comparison needs to split each value into the number and the rest, then compare the numbers first, then the strings if they're equal. So it would be something like:
public sealed class NumberStringComparer : IComparer<string>
{
public int Compare(string x, string y)
{
return NumberString.Parse(x).CompareTo(NumberString.Parse(y));
}
private struct NumberString : IComparable<NumberString>
{
private readonly int? number;
private readonly string text;
private NumberString(int? number, string text)
{
this.number = number;
this.text = text;
}
internal static NumberString Parse(string text)
{
// TODO: Find where the digits stop, parse the number
// (if there is one), call the constructor and return a value.
// (You could use a regular expression to separate the parts...)
}
public int CompareTo(NumberString other)
{
// TODO: Compare numbers; if they're equal, compare
// strings
}
}
}
If you have problems with either of the TODOs (after spending some time trying), you can ask for more specific help - but this is the general approach I'd use.
See more on this question at Stackoverflow