it-swarm.com.ru

цикл по значениям перечисления

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

32
Frank

Дано

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

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

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

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

38
Barry Wark

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

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

8
Brian Postow

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

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

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

for ( int direction = East; direction <= South; ++direction)
{
   /* Do something with Direction
}
7
ennuikiller

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

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

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

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

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

Затем я использую это внутри цикла, как таковой:

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

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

5
CloakedEddy

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

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
Matt Conway

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

{
enum Pig { Snort, Sty, Oink, Curly };
const int Pig_Count = Enum.GetNames(typeof(Pig)).Length;
}
2
GhengisDon

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

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


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

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

1
yeahdixon

Я ненавижу загрязнять мой 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
0
beOn

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

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

for ( int fooInt = One; fooInt != Last; fooInt++ )
{
   Foo foo = static_cast<Foo>(fooInt);
   // ...
}
0
serv-inc