#objective-c #enums #key-value
#objective-c #перечисления #ключ-значение
Вопрос:
Я хочу создать подобный перечислению набор строк таким образом, который также предоставит мне возможность упорядочивать их по порядковому значению, а НЕ по алфавитному значению. например:
«Чрезвычайно низкий» = 0
«Очень низкий» = 1
«Low» = 2
«Средний = 3
«High» = 4
и так далее.
Я знаю, что, например, в Java и C # типы перечислений могут иметь значение помимо их порядкового значения.
Есть ли какой-либо способ достичь той же цели в Objective-C?
Спасибо!
Ответ №1:
Я не знаю прямого способа сделать это. Однако вы можете определить класс Obj-C следующим образом:
@interface EnumLike : NSObject
{
NSString* title;
NSInteger value;
}
@property (nonatomic, readonly) NSString* title;
@property (nonatomic, readonly) NSInteger value;
// Something like enum
(id)extremelyLow;
(id)veryLow;
...
(id)high;
};
За исключением работы с переключателем, это может выполнить работу. Я время от времени использую подобные типы, чтобы объявлять некоторые «перечисления» для пользователя, поскольку список таких экземпляров может быть привязан к NSArrayController и использоваться в пользовательском интерфейсе.
Комментарии:
1. Вау, это великолепно! Это почти именно то, что я ищу. Единственное, чего не хватает, это добавить опцию для создания одного из этих «предопределенных» элементов, указав строку для значения типа «Very Low» и получив обратно соответствующий объект EnumLike. Мне это нужно, потому что я считываю данные из файла, и мне нужно разобрать эти строки во что-то, с чем я могу работать.
Ответ №2:
Просто сохраните строки для ввода-вывода и используйте перечисление для всех ваших вычислений. Например, определите свой enum:
typedef enum { ExtremelyLow, VeryLow, ... High } Rating;
Вы можете использовать это перечисление в switch
инструкциях и т.д. Теперь вы можете использовать NSArray
или просто C-массив для сопоставления литералов перечисления со строками:
NSString *RatingToString[] = { @"Extremely Low", @"Very Low", ..., @"High" };
Rating myRating;
NSString *strMyRating = RatingToString[myRating];
Переход от строковой версии к перечислению более сложный, вы можете использовать тот же RatingToString
массив и выполнить соответствующие сравнения (возможно, без учета регистра, нечеткие и т.д.). Вы также могли бы использовать NSDictionary
:
NSDictionary StringToRating = [NSDictionary dictionaryWithObjectsAndKeys: RatingToString[ExtremelyLow], [NSNumber numberWithInt:ExtremelyLow, ..., nil];
Теперь поиск выполнит точное совпадение с вашей строкой и вернет Rating
завернутое в NSNumber
виде.
Комментарии:
1. Идея словаря выглядит очень хорошо. я могу создать статический массив, подобный этому, и он будет делать именно то, что я хочу — я могу прочитать строку из файла и сразу узнать ее значение, вызвав словарь objectForKey: и передать строку из файла в качестве ключа
2. «NSString *strMyRating = RatingToString[Мой рейтинг];» Вы инициализируете
NSString *
с помощьюchar *
Ответ №3:
Вы можете использовать класс, подобный предложенному Gobra, или массив структур c:
typedef struct {
int type;
NSString *desc;
} NXENumToNSString;
NXENumToNSString kNXGMWidgetTypes[] = {
{1, @""},
{2, @"imageGallery"},
{3, @"dotImageGallery"},
{4, @"video"},
{5, @"webView"},
{6, @"image"}
};
NSInteger
intToStringForArray(NXENumToNSString *buffer, size_t length, NSString *str)
{
int result = NSIntegerMin;
NXENumToNSString *scan, *stop;
scan = buffer;
stop = scan length;
while (scan < stop) {
if ([scan->desc isEqualToString:str]) {
result = scan->type;
break;
}
scan ;
}
return resu<
}
затем вы можете сделать что-то вроде этого:
size_t l = sizeof(kNXGMWidgetTypes) / sizeof(NXENumToNSString);
NSInteger result = intToStringForArray(kNXGMWidgetTypes, l, str);