Есть ли краткий способ сопоставить строку с перечислением в Objective-C? - PullRequest
0 голосов
/ 18 мая 2010

У меня есть строка, которую я хочу проанализировать и вернуть эквивалентное перечисление. Мне нужно использовать тип enum где-то еще, и мне нравится, как я его определяю. Проблема в том, что я не знаю хорошего способа сравнить строку со значениями перечисления без излишнего порядка перечислений.

Нет ли другого варианта, кроме большого 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];
}

В Python я бы, вероятно, сделал что-то вроде следующего, хотя, если честно, я тоже не влюблен в это.

## 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)

пс. Я знаю, что в Какао есть цветовые константы, это всего лишь пример.

Ответы [ 3 ]

3 голосов
/ 18 мая 2010

попробуйте это: Отобразить перечисление в массив символов

Псевдокод .. не проверен.

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

Более объективная версия кода может быть:

// 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;
0 голосов
/ 11 апреля 2012

Я никогда не был удовлетворен ни одним из предложений. (Но я ценю усилия, приложенные к ним.) Я попробовал некоторые из них, но они не чувствовали себя хорошо или были подвержены ошибкам на практике.

В итоге я создал собственный словарь для отображения целых чисел в строки, который выглядит намного лучше, потому что это какао насквозь. (Я не создал подкласс NSDictionary для того, чтобы его было сложнее неправильно использовать.)

@interface ZZEnumDictionary : NSObject {
    NSMutableDictionary *dictionary;
}

+ (id)dictionary;
+ (id)dictionaryWithStrings:(id)firstString, ...;
- (NSString *)stringForInt:(NSInteger)intEnum;
- (NSInteger)intForString:(NSString *)stringEnum;
- (BOOL)isValidInt:(NSInteger)intEnum;
- (BOOL)isValidString:(NSString *)stringEnum;
- (BOOL)stringEquals:(NSString *)stringEnum intEnum:(NSInteger)intEnum;
- (BOOL)setContainsString:(NSSet *)set forInt:(NSInteger)intEnum;
- (NSArray *)allStrings;
@end

@interface ZZEnumDictionary ()
- (void)setInt:(NSInteger)integer forString:(NSString *)string;
@end
0 голосов
/ 18 мая 2010

На этот вопрос уже был дан ответ: Преобразование между C enum и XML

По сути, вы определяете соответствующие строки при определении enum, а затем используете категорию на NSArray, чтобы вы могли сделать это:

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

Конечно, #define немного уродлив, но код выше, с которым вы будете работать большую часть времени, на самом деле довольно чист.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...