How to Iterate Over Values of an Enum Having Flags

How to iterate over values of an Enum having flags?

Coming back at this a few years later, with a bit more experience, my ultimate answer for single-bit values only, moving from lowest bit to highest bit, is a slight variant of Jeff Mercado's inner routine:

public static IEnumerable<Enum> GetUniqueFlags(this Enum flags)
{
ulong flag = 1;
foreach (var value in Enum.GetValues(flags.GetType()).Cast<Enum>())
{
ulong bits = Convert.ToUInt64(value);
while (flag < bits)
{
flag <<= 1;
}

if (flag == bits && flags.HasFlag(value))
{
yield return value;
}
}
}

It seems to work, and despite my objections of some years ago, I use HasFlag here, since it's far more legible than using bitwise comparisons and the speed difference is insignificant for anything I'll be doing. (It's entirely possible they've improved the speed of HasFlags since then anyway, for all I know...I haven't tested.)

Iterate over values in Flags Enum - but keep the order


I now need to iterate through the values but keep the order in which the enum was passed to the methods.

There's no such concept. The | operator doesn't have any way of preserving ordering. To put it another way, imagine we had:

public void Foo(int x)

and you called it with:

Foo(1 + 4)
Foo(2 + 3)

How would you expect it to differentiate? If you need to pass separate values in, with a specific preserved order, you should probably use:

public void ParseColumns(params Column[] columns)

... at which point you may want to avoid it being a flags enum at all.

How to iterate through an enumeration of flags and create checkboxes that are checked appropriately for each value?

I found a good solution.

Here's what I came up with:

@foreach (DayOfWeek item in Enum.GetValues(typeof(DayOfWeek)))
{
if (0 < item && (item <= DayOfWeek.Friday || item == DayOfWeek.Saturday))
{
@Html.Label("DayOfWeek", item.ToString())
@Html.CheckBox("DayOfWeek", (Model.DayOfWeek.HasFlag(item)), new { value = item })
}
}

The conditional statement within the loop is to ensure that only the actual days get displayed.

This works for my purposes, and the concept can be easily applied to other Enumerations. Specific implementation will need some changes, but you get the idea.

Loop through selected Enum values?

How about the following:

FileStatus status = FileStatus.New|FileStatus.Amazing;

foreach (FileStatus x in Enum.GetValues(typeof(FileStatus)))
{
if (status.HasFlag(x)) Console.WriteLine("{0} set", x);
}

Or in one fell LINQ swoop:

var flags = Enum.GetValues(typeof(FileStatus))
.Cast<FileStatus>()
.Where(s => status.HasFlag(s));

How to iterate over all values of an Enum including any nested Enums?

Here's a quick example that just prints them out. I'll leave it as an exercise to the reader to make this a generic generator or whatever applies to the actual use case. :)

>>> from typing import Type
>>> def print_enum(e: Type[Enum]) -> None:
... for p in e:
... try:
... assert(issubclass(p.value, Enum))
... print_enum(p.value)
... except (AssertionError, TypeError):
... print(p)
...
>>> print_enum(Properties)
Properties.height
Properties.weight
Color.blue
Color.red

Check for Enum equals with Enum value composed from Enum flags

I think you're looking for this:

var test = TknType.Numeric;

if ((test & TknType.Numeric) == TknType.Numeric)
{
Console.WriteLine("Test has Numeric flag");
}
else if ((test & TknType.Number) == TknType.Number)
{
Console.WriteLine("Test has Number flag");
}
else if ((test & TknType.Constant) == TknType.Constant)
{
Console.WriteLine("Test has Constant flag");
}

Iterate over Enum elements (Not just names and not just values)

I am not totally following why your extension doesn't work for you (if you have it on the Enum your "requested" code should work).

Here is how I have done this though:

public static class EnumerationExtensions
{
public static string GetDescription(this Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());

DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes( typeof(DescriptionAttribute), false);

return attributes.Length > 0 ? attributes[0].Description : value.ToString();
}
public static IEnumerable<TEnum> GetEnumCollection<TEnum>(bool skipFirst = false)
{
var result = new List<TEnum>();
var enums = Enum.GetValues(typeof(TEnum));
for (int i = 0; i < enums.Length; i++)
{
if (skipFirst && i == 0) continue; //Some enums use "Invalid" or "Default" as first value
TEnum e = (TEnum)enums.GetValue(i);
result.Add(e);
}
return result;
}
}

Also, one thing to think about is why are you needing it. If this is for display purposes, perhaps a IValueConverter is what you should do. This allows you to have a collection of enumeration types and then display the description quite easy as the IValueConverter object receives the enum and then returns the .Description extension call.

The example I provided has a "skipFirst" defaulted to false, because often when I make enumerations I put an invalid sate first (e.g. Default, Undefined etc.) to ensure default state is not valid (I want to ensure something is set and not use a default).

EDIT
Adding the IValueConverter that I have used.

public class EnumerationToDescriptionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var casted = value as Enum;
return casted?.GetDescription();
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
//we have no need to get from visual descirption to the enumeration at this time.
throw new NotImplementedException();
}
}

Then you just need to instantiate your converter as a resource with a key and reference it.

<converters:EnumerationToDescriptionConverter x:Key="EnumerationToDescriptionConverter" />

<TextBlock Text="{Binding Converter={StaticResource EnumerationToDescriptionConverter}}"/>

In my case the TextBlock is within a DataTemplate used for a ItemsControl that is bound to a collection of the enumerations that are retrieved via the other extension method posted above.

enum bitwise/flags Instance enumeration/iteration/foreach

Assuming Suit is a bitwise enum with no overlapping values, then this would be sufficient:

var availableSuits = Enum.GetValues(typeof(Suit)).Cast<Enum>();
foreach (Suit suit in availableSuits.Where(mySuits.HasFlag)) {
// ...
}

If it needs to be fast, or if it needs to ignore composite values or a zero value, then you should probably instead check successive powers of two in a for loop and identify which values match that way.



Related Topics



Leave a reply



Submit