How to Iterate Over an Enum

How to loop through all enum values in C#?

Yes you can use the ‍GetValue‍‍‍s method:

var values = Enum.GetValues(typeof(Foos));

Or the typed version:

var values = Enum.GetValues(typeof(Foos)).Cast<Foos>();

I long ago added a helper function to my private library for just such an occasion:

public static class EnumUtil {
public static IEnumerable<T> GetValues<T>() {
return Enum.GetValues(typeof(T)).Cast<T>();
}
}

Usage:

var values = EnumUtil.GetValues<Foos>();

How can I iterate over an enum?

The typical way is as follows:

enum Foo {
One,
Two,
Three,
Last
};

for ( int fooInt = One; fooInt != Last; fooInt++ )
{
Foo foo = static_cast<Foo>(fooInt);
// ...
}

Please note, the enum Last is meant to be skipped by the iteration. Utilizing this "fake" Last enum, you don't have to update your terminating condition in the for loop to the last "real" enum each time you want to add a new enum.
If you want to add more enums later, just add them before Last. The loop in this example will still work.

Of course, this breaks down if the enum values are specified:

enum Foo {
One = 1,
Two = 9,
Three = 4,
Last
};

This illustrates that an enum is not really meant to iterate through. The typical way to deal with an enum is to use it in a switch statement.

switch ( foo )
{
case One:
// ..
break;
case Two: // intentional fall-through
case Three:
// ..
break;
case Four:
// ..
break;
default:
assert( ! "Invalid Foo enum value" );
break;
}

If you really want to enumerate, stuff the enum values in a vector and iterate over that. This will properly deal with the specified enum values as well.

A for-loop to iterate over an enum in Java

.values()

You can call the values() method on your enum.

for (Direction dir : Direction.values()) {
// do what you want
}

This values() method is implicitly declared by the compiler. So it is not listed on Enum doc.

How to enumerate an enum

foreach (Suit suit in (Suit[]) Enum.GetValues(typeof(Suit)))
{
}

Note: The cast to (Suit[]) is not strictly necessary, but it does make the code 0.5 ns faster.

How to iterate over enum

You can generates a list of cases on an enum with cases() like this:

enum Shapes
{
case RECTANGLE;
case SQUARE;
case CIRCLE;
case OVAL;
}

foreach (Shapes::cases() as $shape) {
echo $shape->name . "\n";
}

The output of this is:

RECTANGLE
SQUARE
CIRCLE
OVAL

for PHP 8.1 and greater.

See: PHP Fiddle

How can I loop through enum values for display in radio buttons?

Two options:

for (let item in MotifIntervention) {
if (isNaN(Number(item))) {
console.log(item);
}
}

Or

Object.keys(MotifIntervention).filter(key => !isNaN(Number(MotifIntervention[key])));

(code in playground)


Edit

String enums look different than regular ones, for example:

enum MyEnum {
A = "a",
B = "b",
C = "c"
}

Compiles into:

var MyEnum;
(function (MyEnum) {
MyEnum["A"] = "a";
MyEnum["B"] = "b";
MyEnum["C"] = "c";
})(MyEnum || (MyEnum = {}));

Which just gives you this object:

{
A: "a",
B: "b",
C: "c"
}

You can get all the keys (["A", "B", "C"]) like this:

Object.keys(MyEnum);

And the values (["a", "b", "c"]):

Object.keys(MyEnum).map(key => MyEnum[key])

Or using Object.values():

Object.values(MyEnum)

What are commonly-used ways to iterate over an enum class in C++?

This is the most-readable and simplest approach I could come up with, but I am open to other peoples' example solutions.

I find this approach to be easy-to-use, similar to my C approach (making it more-portable and more-recognizable), and suitable to C++. It compiles with the -Wall -Wextra -Werror compiler build options.

enum class MyErrorType 
{
SOMETHING_1 = 0,
SOMETHING_2,
SOMETHING_3,
SOMETHING_4,
SOMETHING_5,
/// Not a valid value; this is the number of members in this enum
_COUNT,
// helpers for iterating over the enum
begin = 0,
end = _COUNT,
};

for (MyErrorType myErrorType = (MyErrorType)0;
myErrorType < MyErrorType::_COUNT;
myErrorType = static_cast<MyErrorType>((size_t)myErrorType + 1))
{
switch (myErrorType)
{
case MyErrorType::SOMETHING_1:
break;
case MyErrorType::SOMETHING_2:
break;
case MyErrorType::SOMETHING_3:
break;
case MyErrorType::SOMETHING_4:
break;
case MyErrorType::SOMETHING_5:
break;
case MyErrorType::_COUNT:
// This case will never be reached. It is included only so that when
// compiling with `-Wall -Wextra -Werror` build flags you get the
// added bonus of covering all switch cases (withOUT unnecessarily
// relying on a `default` case which would break this feature!), so
// if you ever add a new element to the enum class but forget to
// add it here to the switch case the compiler will THROW AN ERROR.
// This is an added safety benefit to force you to keep your enum
// and the switch statement in-sync! It's a technique commonly used
// in C as well.
break;
}
}

Read my comments for the MyErrorType::_COUNT case above! If you are using the compiler's -Wall -Wextra -Werror compiler options but do NOT include this case in the switch statement (since those build options require you to cover ALL enum cases in ALL switch statements!), the compiler will throw the following error and stop! This is a great safety feature to ensure you keep the enum definition and all switch cases in-sync, handling all possible enums in all of your switch statements. Here is the compiler error thrown by LLVM's clang compiler (an alternative to gcc):

../my_file.cpp:11:16: error: enumeration value ‘_COUNT’ not handled in switch [-Werror=switch]
11 | switch (myErrorType) {
| ^

One more tiny improvement over the code above, for clarity, would be to add begin and end elements to your enum like this:

enum class MyErrorType 
{
SOMETHING_1 = 0,
SOMETHING_2,
SOMETHING_3,
SOMETHING_4,
SOMETHING_5,
/// Not a valid value; this is the number of members in this enum
_COUNT,
// helpers for iterating over the enum
begin = 0,
end = _COUNT,
};

...so that you can iterate over the enum as follows. The incrementing part of the for loop still is a bit cumbersome with all of the required casts, but the initial state and end condition check are at least much clearer now, since they use MyErrorType::begin and MyErrorType::end:

for (MyErrorType myErrorType = MyErrorType::begin; 
myErrorType < MyErrorType::end;
myErrorType = static_cast<MyErrorType>((size_t)myErrorType + 1))
{
switch (myErrorType)
{
case MyErrorType::SOMETHING_1:
break;
case MyErrorType::SOMETHING_2:
break;
case MyErrorType::SOMETHING_3:
break;
case MyErrorType::SOMETHING_4:
break;
case MyErrorType::SOMETHING_5:
break;
case MyErrorType::_COUNT:
// This case will never be reached.
break;
}
}

Related:

  1. Common techniques for iterating over enums (as opposed to enum classes): How can I iterate over an enum?
    1. [my answer] How can I iterate over an enum?
  2. My answer on some of the differences between enum classes (strongly-typed enums) and regular enums (weakly-typed enums) in C++: How to automatically convert strongly typed enum into int?
  3. Some of my personal notes on the -Wall -Wextra -Werror and other build options, from my eRCaGuy_hello_world repo.
  4. Incrementation and decrementation of “enum class”

Other keywords: common way to iterate over enum or enum class in C or C++; best way to iterate over enum class in C++; enum class C++ iterate; c++ iterate over enum class



Related Topics



Leave a reply



Submit