перебирая значения перечисления - PullRequest
34 голосов
/ 02 ноября 2009

Возможно ли перебрать значения перечисления в Objective-C?

Ответы [ 9 ]

38 голосов
/ 02 ноября 2009

С учетом

enum Foo {Bar=0,Baz,...,Last};

Вы можете перебирать элементы как:

for(int i=Bar; i<=Last; i++) {
  ...
}

Обратите внимание, что это раскрывает действительно простую природу перечисления C. В частности, вы можете видеть, что перечисление C на самом деле не обеспечивает безопасность типов, так как вы можете использовать int вместо значения перечисления и наоборот. Кроме того, это зависит от порядка объявления значений перечисления: по меньшей мере, хрупкий. Кроме того, пожалуйста, смотрите комментарий Чака; если элементы enum не являются смежными (например, потому что вы указали явные непоследовательные значения для некоторых элементов), это не будет работать вообще. Хлоп.

8 голосов
/ 02 ноября 2009

Это что-то вроде клочья (как и вся концепция так ... эх ...), но если вы собираетесь сделать это несколько раз, и вы хотите иметь возможность справиться с возможностью непрерывные перечисления, вы можете создать массив (глобальная константа) и иметь (по примеру ennukiller) Directions directions [4] = {восток, запад, север, юг}; и тогда в вашем цикле вы можете говорить о направлениях [i], а не итерировать непосредственно по самим направлениям ...

Как я уже сказал, это уродливо, но я думаю, что оно немного менее хрупкое ...

7 голосов
/ 02 ноября 2009

Если ваш enum определяется следующим образом:

enum Direction {  East,  West,  North,  South};

Вы можете пройти через это следующим образом:

for ( int direction = East; direction <= South; ++direction)
{
   /* Do something with Direction
}
5 голосов
/ 12 февраля 2016

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

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;
    }
}
5 голосов
/ 19 февраля 2014

В поисках этого я просто придумал следующее решение, которое отвечало моим собственным требованиям. Я думал, что опубликую это здесь для людей, ищущих что-то подобное.

Скажи, что у меня есть перечисление.

typedef NS_ENUM (NSInteger, ISDirection) {
  ISDirectionUp,
  ISDirectionDown,
  ISDirectionLeft,
  ISDirectionRight
};

Чтобы иметь возможность зацикливаться на этом, я определяю следующий макрос препроцессора.

#define ISDirectionAllAsDir ISDirection dir = ISDirectionUp; dir <= ISDirectionRight; dir++

Тогда я использую его внутри цикла, как таковой:

for(ISDirectionAllAsDir) {
  NSLog(@"Direction %d", dir);
}

Это помещает логику для итерации в одно место (макрос), что повышает удобство сопровождения кода.

2 голосов
/ 02 мая 2016

Длина (количество элементов) любого перечисления может быть определена путем получения массива имен в перечислении и использования длины массива.Используйте метод GetNames из Enum.Enum.GetNames (enumType) .Length.

{
enum Pig { Snort, Sty, Oink, Curly };
const int Pig_Count = Enum.GetNames(typeof(Pig)).Length;
}
1 голос
/ 02 октября 2012

Мне нравится то, что я получил отсюда Итерация по enum в Objective C?

typedef enum { ENUM1=0,  ENUM2, ENUM3, ENUM4 , TOTAL  } ;


for ( int i=ENUM1 ; i<TOTAL; i++)
{}

таким образом вы можете продолжать добавлять перечисления позже и не влиять на ваши циклы?

0 голосов
/ 28 декабря 2018

Если вышеописанное не работает для вас, потому что вы используете C ++, следующее должно :

enum Foo {
  One,
  Two,
  Three,
  Last
};

for ( int fooInt = One; fooInt != Last; fooInt++ )
{
   Foo foo = static_cast<Foo>(fooInt);
   // ...
}
0 голосов
/ 08 апреля 2018

Я ненавижу загрязнять мой enum записью "Last" (и сопровождающим примечанием, что его не следует использовать, и что его всегда нужно хранить, ну, в конце концов), и нашел только один способ обойти это (кроме использования последней записи enum в качестве секретного «последнего», что опять же заставляет меня чувствовать себя непривлекательно).

Если вы определите свое перечисление с помощью X Macros , вы можете довольно просто подсчитать количество элементов в вашем перечислении. См. Ссылку FMI о том, когда вы можете использовать этот подход - чтобы быть кратким, вот как это выглядит:

#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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...