Reputation: 8182
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?
Upvotes: 7
Views: 7574
Reputation: 91
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! :-)
Upvotes: 2
Reputation: 39085
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
Upvotes: 4
Reputation: 437386
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.
Upvotes: 5