How to iterate through enum type while skipping some values?

var query = Enum.GetValues(typeof(MyEnum))
    .Cast<MyEnum>()
    .Except(new MyEnum[] { MyEnum.A, MyEnum.E });
foreach (MyEnum item in query) {
    ...
}

You need to cast in order to get the magic of LINQ. Except alone will not do it.


UPDATE:

I got another idea. You can define the enum with the FlagsAttribute and define the regular values as powers of 2, what is most easily achieved with the bitwise shift left operator <<. Starting with C# 7.0, you can also use binary literals like 0b_0000_0000_0010_0000. Then it is possible to combine existing values to form new values.

[Flags]
enum MyEnum
{
    None = 0,
    A = 1 << 0,
    B = 1 << 1,
    C = 1 << 2,
    D = 1 << 3,
    E = 1 << 4,
    ...
    X = 1 << 23,
    Y = 1 << 24,
    Z = 1 << 25,
    Vowels = A | E | I | O | U
}

Now, you can formulate the query like this

IEnumerable<MyEnum> query = Enum.GetValues(typeof(MyEnum))
    .Cast<MyEnum>()
    .Where(x => (x & MyEnum.Vowels) == MyEnum.None);
foreach (MyEnum item in query) {
    ...
}

The advantage over the first solution is, that you can perform the test with a single bitwise AND-operation.

You can define up to 32 powers of two. If you need more, you can define the base type of the enum as long and use up to 64 flag values (plus combinations of existing flag values).

[Flags]
enum MyEnum : long
{
    ...
}

I'd probably just use LINQ - use Enum.GetValues (or use Unconstrained Melody - a type-safe generic enum/delegate library I wrote) to get all the values, then express which values to keep/skip via a Whereclause.

If you're only skipping specific values, a HashSet or something similar may be useful (not worth it if you're only skipping one, of course) - if you're skipping based on a condition, then a full-blown predicate is called for.

For example:

public static IEnumerable<T> AllBut<T>(T skipped) where T : struct
{
    IEqualityComparer<T> comparer = EqualityComparer<T>.Default;
    return AllBut<T>(t => !comparer.Equals(skipped, t));
}

public static IEnumerable<T> AllBut<T>(Func<T, bool> skipPredicate) where T : struct
{
    IEqualityComparer<T> comparer = EqualityComparer<T>.Default;
    return Enum.GetValues(typeof(T))
               .Cast<T>()
               .Where(t => skipPredicate(t));
}

I would make a separate set of elements consisting of vowels, and then take the set difference between the two sets using LINQ.

int[] vowels = {Letters.A, Letters.E, Letters.I, Letters.O, Letters.U};
IEnumerable<int> consonant = Enum.GetValues(typeof(Letters)).Except(vowels);
foreach (int consonant in consonants)
{
    // Do something with each consonant
}