Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to perform LINQ query over Enum?

Below is my Enumerator List:

public enum StatusEnum
{
    Open = 1,
    Rejected = 2,
    Accepted = 3,
    Started = 4,
    Completed = 5,
    Cancelled = 6,
    Assigned = 7
}

I need to bind this to a Combobox, but, only show a few specific statuses and ignore the rest.

This is what I have so far:

public static List<Activity.StatusEnum> StatusList()
{
        IEnumerable<Activity.StatusEnum> query = Enum.GetValues(typeof(Activity.StatusEnum)).Cast<Activity.StatusEnum>()
                        .Where(x => x == Activity.StatusEnum.Open
                            || x == Activity.StatusEnum.Rejected
                            || x == Activity.StatusEnum.Accepted
                            || x == Activity.StatusEnum.Started);
        return query.ToList();
}

However, I feel that the code is little messy and is not a correct approach to bind filtered Enum list to a Combobox. Can anyone suggest a more robust way of doing this?

Update

I might need to change the Order of selection. So I need a generic solution which doesn't only get the first X number of statuses.

like image 921
Learner Avatar asked Jun 13 '13 16:06

Learner


4 Answers

return Enum.GetValues(typeof(Activity.StatusEnum)).Cast<Activity.StatusEnum>().Where((n, x) => x < 4);

If you want to be able to change the list of items, just add them into a List<Activity.StatusEnum> and use Contains:

var listValid = new List<Activity.StatusEnum>() { Activity.StatusEnum.Open, Activity.StatusEnum.Rejected, Activity.StatusEnum.Accepted, Activity.StatusEnum.Started };
return Enum.GetValues(typeof(Activity.StatusEnum)).Cast<Activity.StatusEnum>().Where(n => listValid.Contains(n));
like image 144
It'sNotALie. Avatar answered Nov 15 '22 06:11

It'sNotALie.


Well if you're going to hard code the items that should be in the list anyway, why not just do this:

public static List<Activity.StatusEnum> StatusList()
{
    return new List<Activity.StatusEnum>
    { 
        Activity.StatusEnum.Open, 
        Activity.StatusEnum.Rejected, 
        Activity.StatusEnum.Accepted, 
        Activity.StatusEnum.Started 
    };
}

You could also dispose of the List<T> and just return the array itself. As long as you know these are the items you want, then there's no need for Linq.

like image 34
p.s.w.g Avatar answered Nov 15 '22 06:11

p.s.w.g


Steps:

  • Get the enum values and cast the results to the type of the enum
  • Sort the enum values by their integer values (otherwise they sort naturally by unsigned magnitude)
  • Take the first 4

Code:

return Enum.GetValues(typeof(Activity.StatusEnum))
.Cast<Activity.StatusEnum>()
.OrderBy(se =>(int)se)
.Take(4);

Output:

Open Rejected Accepted Started

like image 12
Stephen Kennedy Avatar answered Nov 15 '22 04:11

Stephen Kennedy


First, if possible, I'd make your enum values powers of 2, so they could be OR'd together.

public enum StatusEnum
{
    Open = 1,
    Rejected = 2,
    Accepted = 4,
    Started = 8,
    Completed = 16,
    Cancelled = 32,
    Assigned = 64
}

Then you could do something like this:

public static List<Activity.StatusEnum> StatusList()
{
    var statusesToShow = Activity.StatusEnum.Open | Activity.StatusEnum.Rejected | Activity.StatusEnum.Accepted | Activity.StatusEnum.Started;

    return Enum
        .GetValues(typeof(Activity.StatusEnum))
        .Cast<Activity.StatusEnum>()
        .Where(x => (x & statusesToShow) == x)
        .ToList();
}

EDIT: In light of the fact that you can't change the enum values, I'd just recommend you use something like:

public static List<Activity.StatusEnum> StatusList()
{
    return new List<Activity.StatusEnum> {
        Activity.StatusEnum.Open, 
        Activity.StatusEnum.Rejected, 
        Activity.StatusEnum.Accepted, 
        Activity.StatusEnum.Started
    };
}
like image 8
Chris Doggett Avatar answered Nov 15 '22 05:11

Chris Doggett