简体   繁体   English

比较Enum值进行排序

[英]Comparing Enum values for sorting

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, ...) 我想要它们的排序顺序是不一样的(像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? 这可以更有效吗?

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. 当然,您可能希望将sortOrder的初始化移到函数外部,以便它只运行一次。

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: 如果您想要做的只是CompareTo ,那么我认为您可以通过使用字典来简化这一点:

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 . 但是 ,我不确定为什么要实现一个名为CompareTo的扩展方法,但我希望你不要指望它覆盖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: 而不是枚举ValuesOrdered使用静态只读SortedList(你不能使用常量为SortedList),如下所示:

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: 方法“CompareTo”将是这样的:

public static int CompareTo(this Values x, Values y)
    {
        return Comparer<int>.Default.Compare(ordered[x], ordered[y]);
    }

Enjoy! 请享用! :-) :-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM