I want to implement a custom string IComparer
in C# and apply it to a ComboBox.
Actual Results
If I set the ComboBox
's Sorted
property to true
, the output is :
A
AA
AAA
B
BB
BBB
Wanted Results
The wanted behavior of the sorting algorithm is the following (financial developers will understand why :) ) :
AAA
AA
A
BBB
BB
B
Question
Is it possible to do it ? Are sorting algorithms needed here ?
PS : I don't need a complete answer with code, i just need an idea of how it might be done ..
EDIT
This is about credit ratings. I've omitted something in my question. The ratings have to be sorted in this order :
XXX
XX+
XX
XX-
X+
X
X-
with X in ('A','B','C')
and 'A' > 'B' > 'C'
The strcmp() function, is used to compare the strings (str1,str2). The strings str1 and str2 will be compared using this function. If the function returns a value 0, it signifies that the strings are equal otherwise, strings are not equal.
In C, string values (including string literals) are represented as arrays of char followed by a 0 terminator, and you cannot use the == operator to compare array contents; the language simply doesn't define the operation.
Using String. equals() :In Java, string equals() method compares the two given strings based on the data/content of the string. If all the contents of both the strings are same then it returns true. If any character does not match, then it returns false.
You should not use == (equality operator) to compare these strings because they compare the reference of the string, i.e. whether they are the same object or not. On the other hand, equals() method compares whether the value of the strings is equal, and not the object itself.
Here's a mostly implemented version:
public class MyComparer : IComparer<string>
{
public int Compare(string x, string y)
{
//todo null checks on input
var pairs = x.Zip(y, (a, b) => new { x = a, y = b });
foreach (var pair in pairs)
{
int value = pair.x.CompareTo(pair.y);
if (value != 0)
return value;
}
//if we got here then either they are the same,
//or one starts with the other
return y.Length.CompareTo(x.Length); //note x and y are reversed here
}
}
So this uses Zip
to get the pairs of chars from each corresponding string until one ends, returning the appropriate value if they aren't equal. If it makes it past that then one string start with the other. For a traditional string comparison we'd just compare the lengths in the same order as the input parameters. Since we're essentially reversing the order based on length, note that the x
and y
are swapped on the last line. That reverses the comparison logic.
Assuming this is for credit ratings, normally this is done by having a "sort order" column on the CreditRating
class that you could use to sort the list before assigning it as the data source of the drop-down.
But, a quick workaround (based on the limited possible values) would be to sort by the first letter ascending, then by the length of the string descending:
if(left[0] != right[0])
return left[0].CompareTo(right[0]);
else
return right.Length - left.Length;
Another workaround if you want more control over the order is to create a list of possible values in the "right" order and then use that to sort the list:
public class MyComparer : IComparer<string>
{
private static readonly string[] Ratings = new [] {
"CC","C","CCC-","CCC","CCC+",
"B-","B","B+","BB-","BB","BB+","BBB-","BBB","BBB+",
"A-","A","A+","AA-","AA","AA+","AAA"};
// reverse the order so that any strings not found will be put at the end.
public int Compare(string left, string right)
{
return Array.IndexOf(Ratings, right).CompareTo(Array.IndexOf(Ratings, left));
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With