views:

72

answers:

2

I have a string I want to parse and return an equivalent enum. I need to use the enum type elsewhere, and I think I like how I'm defining it. The problem is that I don't know a good way to check the string against the enum values without being redundant about the order of the enums.

Is there no option other than a big if/else?

typedef enum {
    ZZColorRed,
    ZZColorGreen,
    ZZColorBlue,
} ZZColorType;


- (ZZColorType)parseColor:(NSString *)inputString {
    // inputString will be @"red", @"green", or @"blue" (trust me)
    // how can I turn that into ZZColorRed, etc. without
    // redefining their order like this?

    NSArray *colors = [NSArray arrayWithObjects:@"red", @"green", @"blue", nil];
    return [colors indexOfObject:inputString];
}

In Python, I'd probably do something like the following, although to be honest I'm not in love with that either.

## maps  url text -> constant string
RED_CONSTANT = 1
BLUE_CONSTANT = 2
GREEN_CONSTANT = 3

TYPES = {
    'red': RED_CONSTANT,
    'green': GREEN_CONSTANT,
    'blue': BLUE_CONSTANT,
}

def parseColor(inputString):
    return TYPES.get(inputString)

ps. I know there are color constants in Cocoa, this is just an example.

+1  A: 

try this: Map enum to char array

Pseudo code.. untested.

int lookup(const char* str) {
    for(name = one; name < NUMBER_OF_INPUTS; name++) {
        if(strcmp(str, stats[name]) == 0) return name;
    }
    return -1;
}

A more objective-c'ish version of the code could be:

// build dictionary
NSMutableDictionary* dict = [[NSMutableDictionary alloc] init];
for(i=0; i<number_of_strings; i++) {
    [dict setObject:[NSNumber numberWithInteger:i] forKey:[NSString stringWithUTF8String:names[i]]];
}

// elsewhere... lookup in dictionary
id obj = [dict objectForKey:name];
if(obj) return [obj intValue];
return -1;
neoneye
That's not so bad. I can tack on one more enum value ZZColorMax so I don't have to hardcode number-of-strings.
zekel
+1 the dictionary is probably the best way to go.
Dave DeLong
A: 

This has already been answered: http://stackoverflow.com/questions/1242914/converting-between-c-enum-and-xml

Basically, you wind up defining corresponding strings when you define your enum, and then you use a category on NSArray so that you can do this:

static NSArray* colorNamesArray = [[NSArray alloc] initWithObjects:colorNames];
//colorNames is a nil-terminated list of string literals #defined near your enum
NSString* colorName = [colorNamesArray stringWithEnum:color];
//stringWithEnum: is defined with a category

Sure, the #define is a little ugly, but the code above, which is what you'll work with most of the time, is actually pretty clean.

andyvn22