In a project I have an external enum (generated from a service reference). So I cannot change the enum values.
How can I compare those enum values to each other in an effective way?
Here an example for an enum
public enum Values
{
A,
B,
C,
D,
E,
F,
G,
H
}
And the sortorder I want them is not the same (something like F, H, A, C, B, ...)
Right now I have a extension method with some comparisons. (having another enum with the order I want)
public static int CompareTo(this Values x, Values y)
{
var orderedX = GetOrderedValues(x);
var orderedY = GetOrderedValues(y);
return orderedX.CompareTo(orderedY);
}
internal enum ValuesOrdered
{
F = 0,
H = 1,
C = 2,
D = 3,
B = 4,
A = 5,
E = 6,
G = 7
}
internal static ValuesOrdered GetOrderedValues(this Values x)
{
switch (x)
{
case Values.A:
{
return ValuesOrdered.A;
}
// and so on...
}
}
Can this be achieved more effective?
If you just create a list of the enum values (instead of strings) via parsing, then sort that list using Collections. sort , it should sort the way you want. If you need a list of strings again, you can just convert back by calling name() on each element.
There are two ways for making comparison of enum members :equals method uses == operator internally to check if two enum are equal. This means, You can compare Enum using both == and equals method.
By the way unlike comparing String in Java, you can use both == and equals() method to compare Enum, they will produce same result because equals() method of Java. lang. Enum internally uses == to compare enum in Java.
I believe the simplest would be to implement your comparison function in this manner:
public static int CompareTo(this Values x, Values y)
{
var sortOrder = new[] {
Values.F,
Values.H,
Values.C,
Values.D,
Values.B,
Values.A,
Values.E,
Values.G
};
return Array.IndexOf(sortOrder, x) - Array.IndexOf(sortOrder, y);
}
Of course you would want to move the initialization of sortOrder
outside the function so that it only runs once.
Regarding the choice of array as the data structure that encodes the desired ordering: not only is it the simplest, but for such a small number of items linear search is likely also fastest.
If all you want to do is CompareTo
, then I think you could simplify this a bit by using a dictionary:
static Dictionary<Values, int> order = new Dictionary<Values, int>
{
{Values.A, 3},
{Values.B, 5},
{Values.C, 4},
{Values.D, 6},
{Values.E, 8},
{Values.F, 1},
{Values.G, 7},
{Values.H, 2}
};
public static int CompareTo(this Values x, Values y)
{
return order[x].CompareTo(order[y]);
}
However, I'm not sure why want to implement an extension method named CompareTo, but I hope you don't expect it to override the Enum.CompareTo
. For example,
var values = Enum.GetValues(typeof(Values)).Cast<Values>().ToArray();
Array.Sort(values);
Console.WriteLine(string.Join(" ", values));
//OUTPUT: A B C D E F G H
instead to enum ValuesOrdered use static readonly SortedList (you cannot use constant for SortedList) like this:
private static readonly SortedList<Values, int> ordered = new SortedList<Values, int>
{
{Values.F,0},
{Values.H,1},
{Values.C,2},
{Values.D,3},
{Values.B,4},
{Values.A,5},
{Values.E,6},
{Values.G,7},
};
And method "CompareTo" will be like this:
public static int CompareTo(this Values x, Values y)
{
return Comparer<int>.Default.Compare(ordered[x], ordered[y]);
}
Enjoy! :-)
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