将枚举值列表减少为单个int

时间:2013-12-14 22:21:14

标签: c#

我有一个枚举,用于指定某些数据的类别(列)。我希望能够存储排序顺序,因此这些枚举的列表作为单个int值。因此,无论列表的大小(在合理范围内),都有一个可以重建列表的唯一int。

    public enum SortingCategories
    {
        ORDER_DATE = 1,
        CUSTOMER_STATE = 2,
        CUSTOMER_NAME = 3,
        CUSTOMER_HAIRCOLOR = 4,
        ...
    }

    public IEnumerable<SortingCategories> GetSortingOrder(int code)
    {
        ...
    }

    public int GetSortingCode(IEnumerable<SortingCategories> order)
    {
        ...
    }

    public const List<SortingCategories> PossibleSortingOrder = new List<SortingCategories>()
    {
        SortingCategories.CUSTOMER_NAME,
        SortingCategories.CUSTOMER_STATE,
        SortingCategories.ORDER_DATE,
        SortingCategories.CUSTOMER_HAIRCOLOR
    };

    public const List<SortingCategories> AnotherPossibleSortingOrder = new List<SortingCategories>()
    {
        SortingCategories.CUSTOMER_STATE,
        SortingCategories.CUSTOMER_HAIRCOLOR
    };

3 个答案:

答案 0 :(得分:2)

如果它们是&lt;连接值如何? 10

例如

1324
2341
4231

答案 1 :(得分:1)

传统上,解决方案是使用二进制标志来实现此目的。这使您可以保存选项,但不保存订单。除非您为每个合法组合创建标记,否则无法保存选择和单个数字中的顺序。但是,您可以为此类列表构建自己的自定义字符串格式。即{3} {6} {1}并在进行排序之前将这些值强制转换为SortingCategories

以下是flags选项的外观。

public enum SortingCategories
{
    ORDER_DATE = 0x1,
    CUSTOMER_STATE = 0x2,
    CUSTOMER_NAME = 0x4,
    CUSTOMER_HAIRCOLOR = 0x8,
    ...
}

然后使用二元运算符。即)

uint categories = SortingCategories.ORDER_DATE | SortingCategories.CUSTOMER_NAME;

if((categories & SortingCategories.ORDER_DATE) == SortingCategories.ORDER_DATE)
    do something...

答案 2 :(得分:0)

假设您已设置枚举,其中每个值的唯一幂为2,如下所示:

[Flags]
public enum SortingCategories
{
    ORDER_DATE = 1,
    CUSTOMER_STATE = 2,
    CUSTOMER_NAME = 4,
    CUSTOMER_HAIRCOLOR = 8,
}

您可以使用Aggregate扩展名方法:

var myEnumList = new List<SortingCategories>()
{
    SortingCategories.CUSTOMER_NAME,
    SortingCategories.CUSTOMER_STATE,
    SortingCategories.ORDER_DATE,
    SortingCategories.CUSTOMER_HAIRCOLOR
};

var myEnumValue = myEnumList.Aggregate((x, y) => x | y);

更新这是Rob van der Veer's回答的概括,适用于最多9个成员的enum类型,或者更适用于enum类型的<{1}}类型em> n 成员可以编码最多 log n (2 31 -1)项目的列表。它将确保您可以解码整数以获取原始列表,包括项目在列表中出现的顺序:

// Get the number of members in the enum type
// Note, you could hard code this as a private const as well
int numberOfMembers = Enum.GetValues(typeof(SortingCategories)).Length;


// Get integer value from enum list
int EnumListToInt(IEnumerable<SortingCategories> list, int numberOfMembers)
{
    return list.Aggregate(
        new { i = 0, p = 1 },
        (a, e) => new { i = (a.i + (int)e * a.p), p = a.p * numberOfMembers },
        a => a.i);
}

// Get integer value representing list
List<SortingCategories> EnumListToInt(int intVal, int numberOfMembers)
{
    return Enumerable.Range(1, numberOfMembers).Select(
        p => {
            var result = intValue % numberOfMembers;
            intValue /= numberOfMembers;
            return (SortingCategories)result;
        }).ToList();
}

请注意,与前一个方法不同,此方法假定枚举值的范围为0到 N ,就好像您没有为枚举成员指定任何显式值。这可以通过使用以下内容来修改以支持任何值:

int numberOfMembers = Enum.GetValues(typeof(SortingCategories)).Cast<int>().Max() + 1;