Reputation: 3121
Is it possible to loop through enum values in Objective-C?
Upvotes: 44
Views: 94722
Reputation: 6934
I like what I got from Iteration over enum in Objective-C:
typedef enum {ENUM1=0, ENUM2, ENUM3, ENUM4, TOTAL};
for ( int i=ENUM1; i<TOTAL; i++)
{}
That way, you can keep adding enums later on and not affecting your loops.
Upvotes: 1
Reputation: 46965
If your enum is defined as follows:
enum Direction { East, West, North, South};
You can loop through it this way:
for ( int direction = East; direction <= South; ++direction)
{
/* Do something with 'Direction' */
}
Upvotes: 9
Reputation: 38247
If the above does not work for you, because you're using C++, the following should:
enum Foo { One, Two, Three, Last }; for ( int fooInt = One; fooInt != Last; fooInt++ ) { Foo foo = static_cast<Foo>(fooInt); // ... }
Upvotes: 1
Reputation: 1919
I hate dirtying up my enum with a "Last" entry (and the accompanying note that it shouldn't be used, and that it always hast to be kept, well, last), and have only found one way around it (other than using the last enum entry as a secret "last," which, again, makes me feel icky).
If you define your enum using X Macros, you can get a count of the number of items in your enum pretty simply. See the link FMI on when you might use this approach - to keep things brief, here's what it looks like:
#define COLOR_TABLE \
X(red, "red") \
X(green, "green") \
X(blue, "blue")
#define X(a, b) a,
enum COLOR {
COLOR_TABLE
};
#undef X
#define X(a, b) b,
char *color_name[] = {
COLOR_TABLE
};
#undef X
#define X(a, b) +1
int color_count = 0 COLOR_TABLE;
#undef X
Upvotes: 2
Reputation: 107754
Given
enum Foo {Bar=0,Baz,...,Last};
you can iterate the elements like:
for(int i=Bar; i<=Last; i++) {
...
}
Note that this exposes the really-just-an-int nature of a C enum. In particular, you can see that a C enum doesn't really provide type safety, as you can use an int in place of an enum value and vice versa. In addition, this depends on the declaration order of the enum values: fragile to say the least. In addition, please see Chuck's comment; if the enum items are non-contiguous (e.g. because you specified explicit, non-sequential values for some items), this won't work at all. Yikes.
Upvotes: 56
Reputation: 21
The length (count of items) of any enumeration can be ascertained by getting the array of names in the enumeration and utilizing the array's length. Use the GetNames method of Enum. Enum.GetNames(enumType).Length.
{
enum Pig { Snort, Sty, Oink, Curly };
const int Pig_Count = Enum.GetNames(typeof(Pig)).Length;
}
Upvotes: 2
Reputation: 237
For non-contiguous enums you can iterate over valid values by doing:
enum {
value_one = 0,
value_two = 1,
value_three = 3,
value_max
}
for ( i = value_one; i < value_max; i++ )
{
switch(i)
{
case value_one:
case value_two:
case value_three:
case value_four:
{
/* ... Do something with valid enum value ... */
}
break;
default:
/* Found an invalid enum entry; ignore it */
break;
}
}
Upvotes: 7
Reputation: 1995
In search of this, I just concocted the following solution which fulfilled my own requirements. I thought I'd post it here for people searching something similar.
Say I have an enum.
typedef NS_ENUM (NSInteger, ISDirection) {
ISDirectionUp,
ISDirectionDown,
ISDirectionLeft,
ISDirectionRight
};
To be able to loop over it, I define the following preprocessor macro.
#define ISDirectionAllAsDir ISDirection dir = ISDirectionUp; dir <= ISDirectionRight; dir++
Then I use it inside a loop, as such:
for(ISDirectionAllAsDir) {
NSLog(@"Direction %d", dir);
}
This puts the logic for iterating in one place (the macro) which increases code maintainability.
Upvotes: 6
Reputation: 12187
It's a bit of a kludge (as is the entire concept so... eh...) but if you're going to do this multiple times, and you want to be able to deal with the possibility of non-contiguous enums, you can create a (global constant) array, and have (to use ennukiller's example) Directions directions[4] = {East, West, North, South}; and then in your loop you can talk about directions[i] rather than iterating directly over the directions themselves...
As I said, it's ugly, but it's slightly less fragile I think...
Upvotes: 10