44

I have

enum Colour {
    white,
    pink,
    yellow,
    blue
} Colour;

and I would like to do something like this:

for (int colour in Colour){
    // Do something here.
}

Can I do this and if yes, how? Thanks for your help!

Matt N.
  • 1,239
  • 2
  • 11
  • 26
  • 1
    possible duplicate of [looping through enum values](http://stackoverflow.com/questions/1662719/looping-through-enum-values) – Bo Persson Oct 02 '12 at 18:20

6 Answers6

155

Although the question is already answered, here are my two cents:

enum Colour {
    white = 0,
    pink,
    yellow,
    blue,

    colorsCount // since we count from 0, this number will be blue+1 and will be actual 'colors count'
} Colour;

for (int i = 0; i < colorsCount; ++i)
  someFunc((Colour)i);

I guess it's not that bad and is pretty close to the fast enumeration you want.

Gobra
  • 4,263
  • 2
  • 15
  • 20
  • That's in fact what I ended up implementing, thanks for posting it! – Matt N. Aug 02 '11 at 10:56
  • I'm getting errors because I `typedef`ed my enum. Is there a work around for this situation? – abc123 Jul 08 '13 at 18:28
  • 19
    Clever idea, but bad smell. Sneaking functionality into an identification mechanism like an enum breaks its intent and its cohesion. – dooleyo Aug 08 '13 at 07:52
  • 3
    dooleyo, this kind of 'enumeration' is pretty typical for C/C++ coders. Of course, it works only for particular numeric enums. – Gobra Aug 08 '13 at 08:42
  • 1
    The only problem with this idea is that when you do a switch statement on it you'd have to start always catering for this extra enum – Henry Heleine Nov 06 '19 at 19:33
  • 1
    What if I want pink to be 5, then automatically yellow would be 6, right? Then how should the 4 missed cases(1,2,3,4) would be handled ? also I can change pink case value to 60, 600 and so on. – Harish Pathak Nov 18 '19 at 05:32
18

an enum comes from C while fast enumeration was an addition of Objective-C 2.0.. they don't work together.

Type existingItem;
for ( existingItem in expression ) { statements }

expression must conform to the NSFastEnumeration Protocol and be an Object! "elements" of an enum are not objects.

see this link for more information Apple's Fast Enumeration Documents

check this example to see how fast enumeration works:

NSArray *array = [NSArray arrayWithObjects:
        @"One", @"Two", @"Three", @"Four", nil];

for (NSString *element in array) {
    NSLog(@"element: %@", element);
}

NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
    @"quattuor", @"four", @"quinque", @"five", @"sex", @"six", nil];

NSString *key;
for (key in dictionary) {
    NSLog(@"English: %@, Latin: %@", key, [dictionary objectForKey:key]);
}
MJB
  • 3,934
  • 10
  • 48
  • 72
13

"Count" element in enum is nice, but it will get you "Not all switch cases were handled" in switch statement unless you handle this "count" element in it. Maybe a little better way is to use aliases for the first and for the last elements:

enum Colour {
    firstColour = 0,

    white = firstColour,
    pink,
    yellow,
    blue,

    lastColour = blue
} Colour;

for (int i = firstColour; i <= lastColour; ++i) {

}
Alexey Kozhevnikov
  • 4,249
  • 1
  • 21
  • 29
6

I came to this post to answer this question as well. Gobra's answer is great. But my number of items may fluctuate, and correlate to a stored value, so to be extra safe that the "colorsCount" count is or was never a valid value, I ended up implementing the following and wanted to add to the discussion:

MYColor.h

typedef NS_ENUM( NSInteger, MYColorType )
{
    MYColorType0 = 0,
    MYColorType1,
    MYColorType2,
    MYColorType3
};

static inline MYColorType MYColorTypeFirst() { return MYColorType0; }
static inline MYColorType MYColorTypeLast() { return MYColorType3; }

ViewController.m

for ( int i = MYColorTypeFirst(); i <= MYColorTypeLast(); i++ )
{
    MYColor * color = [[MYColor alloc] initWithType:i];
    ...
}

The notable addition being the definition of MYColorTypeFirst() and MYColorTypeLast(), which is used in the for() iteration, placed near the enum definition for maintainability.

Azeven
  • 138
  • 1
  • 6
5

For cases where I'm not the author of the enum, I do it like this. I think this is pretty future safe, as it doesn't cares about how the enum types are actually implemented.

    UISwipeGestureRecognizerDirection allDirections[] = {
        UISwipeGestureRecognizerDirectionDown,
        UISwipeGestureRecognizerDirectionLeft,
        UISwipeGestureRecognizerDirectionRight,
        UISwipeGestureRecognizerDirectionUp
    };

    for (int i = 0; i < sizeof(allDirections)/sizeof(allDirections[0]); ++i) {
        UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(onSwipe:)];
        swipeGesture.direction = allDirections[i];
        [self addGestureRecognizer:swipeGesture];
    }
chunkyguy
  • 3,509
  • 1
  • 29
  • 34
0

This is a perfect use case for using a pre-processor to avoid dirtying up your compiled code


In your .h:

typedef NS_ENUM(NSUInteger, EnumValue)
{
    EnumValueOne,
    EnumValueTwo,
    EnumValueThree,
    EnumValueFour
#define EnumValueLast EnumValueFour
};

Elsewhere in app:

for (EnumValue value = 0; value <= EnumValueLast; value++) {
    //do stuff
}
Albert Renshaw
  • 17,282
  • 18
  • 107
  • 195