2009-11-02 11 views
29

Czy można przeliczyć wartości wyliczenia w Objective-C?zapętlenie wartości wyliczeniowych

+0

Retagged: jest (AFAIK) czystego C pytanie. Otrzymasz więcej odpowiedzi z bardziej ogólnym tagowaniem. –

+14

Odpowiada również na pytanie dla osób szukających go w Obj-C. Dodano ten tag z powrotem. – pbh101

Odpowiedz

7

Jeśli enum jest zdefiniowany następująco:

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

Można pętli tym w ten sposób:

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

Nigdy tego nie robiłem, więc mam kilka pytań. Czy nie powinno to być Direction.East and Direction.South? Również warunek nie powinien być kierunkiem <= Direction.South? Znowu nigdy tego nie robiłem, nie próbuję cię poprawić, po prostu chciałbym się uczyć. –

+3

Czy jest lepszy sposób to zrobić? Po prostu ciekawy, ale wydaje się, że w zależności od kolejności deklaracji wartości wyliczeniowych jest w najlepszym wypadku kruchy. –

+0

@blaenk: Myślę, że masz mylące struktury z wyliczeniami. – pxl

36

Biorąc

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

można iteracyjne elementów, takich jak:

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

Należy zauważyć, że ujawnia to rzeczywiście-po prostu-int-naturę C enum. W szczególności można zauważyć, że C enum w rzeczywistości nie zapewnia bezpieczeństwa typu, ponieważ można użyć int zamiast wartości wyliczeniowej i na odwrót. Ponadto zależy to od kolejności deklaracji wartości wyliczeniowych: co najmniej delikatne. Ponadto, zobacz komentarz Chucka; jeśli elementy wyliczeniowe nie sąsiadują ze sobą (na przykład z powodu podania jawnych, niesekwencyjnych wartości niektórych elementów), nie będzie to w ogóle działać. Yikes.

+8

Wymaga również, aby wszystkie elementy w wyliczeniu były ciągłe. Ale to najlepsze, co dostaniesz. – Chuck

+0

nie rozpoznaje Foo w moim sklepie. – Frank

+6

To czysty nitpick, ale jest napisane "vice versa". – new123456

8

To trochę kludge (jak cała koncepcja, więc ... eh ...), ale jeśli masz zamiar zrobić to wiele razy, i chcesz być w stanie poradzić sobie z możliwością - ciągłe wyliczenia, możesz utworzyć tablicę (stałej globalnej) i mieć (aby użyć przykładu ennukillera) Kierunki dojazdu [4] = {Wschód, zachód, północ, południe}; a następnie w pętli można mówić o kierunkach [i] zamiast iteracji bezpośrednio nad kierunkami siebie ...

Jak powiedziałem, to jest brzydki, ale to nieco mniej kruche myślę ...

+0

Wygląda dobrze dla mnie. Czy istnieje sposób, aby dodać makro, które automatycznie wygeneruje dla nas tablice C dla każdego rodzaju deklarowanego przez nas wyliczenia? – ArtOfWarfare

+1

@ArtOfWarfare Używam tego cały czas: '#define ENUM (type, ...) enum _ ## type {__VA_ARGS__}; enum _ ## typ type ## s [] = {__VA_ARGS__} ', ale to będzie działać tylko dla sąsiadujących. Nie używam nieciągłych wyrażeń, ponieważ to mi sygnalizuje zły projekt. Mam również 'typedef struct _list List;', 'typedef enum _direction Direction' wszędzie w moim kodzie C, który używa tego makra, dlatego przedrostkiem _ jest typ. 'ENUM (kierunek, PÓŁNOC, WSCHÓD, POŁUDNIE, ZACHÓD);' daje 'enum _direction {NORTH, EAST, SOUTH, WEST}; enum _direction directions = {PÓŁNOC, WSCHÓD, POŁUDNIE, ZACHÓD}; "Podoba mi się. –

1

Lubię to, co mam stąd Iteration over enum in Objective C?

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


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

ten sposób można zachować na później dodając teksty stałe i nie wpływa na pętli?

5

W poszukiwaniu tego, właśnie wymyśliłem następujące rozwiązanie, które spełniło moje własne wymagania. Pomyślałem, że opublikuję to tutaj dla osób szukających czegoś podobnego.

Powiedz, że mam wyliczenie.

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

Aby móc wykonać pętlę, definiuję następujące makro preprocesora.

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

Następnie używać wewnątrz pętli, w następujący sposób:

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

Stawia logikę iteracji w jednym miejscu (makro), która zwiększa kodu konserwacji.

3

Dla nieciągłych teksty stałe można iteracyjne nad prawidłowych wartości, wykonując:

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; 
    } 
} 
+0

W tym przypadku nie używałbym w ogóle pętli. Po prostu zostaw klocki rozdzielacza jedna po drugiej, będzie czystsza, a czasami wydajniejsza. –

+0

Oczywiście, całkowicie się z tobą zgadzam i nie zapisałbym tego w kodzie produkcji; jedynym powodem, dla którego zamknąłem przełącznik w pętli, jest to, o co go pytał oryginalny plakat;) –

2

długość (ilość elementów) dowolnego wyliczenie może być ustalona przez coraz tablicę nazw w wyliczeniu i wykorzystywania długość tablicy. Użyj metody GetNames w Enum. Enum.GetNames (enumType) .Długość.

{ 
enum Pig { Snort, Sty, Oink, Curly }; 
const int Pig_Count = Enum.GetNames(typeof(Pig)).Length; 
} 
-3
enum direction = {South, North, East, West}; 

//this is used to loop through enum in the while loop, and will contain the enum length when the while loop finishes. 
int index = 0; 
while(direction[index] != null){ 
    index++; 
} 

//loop through all the values in the enum 
for (int i = 0; i < index; i++){ 
    //your code here, 'direction[index]' will return the enum name 
} 
+2

Oryginalny post (OP) dotyczył iteracji poprzez wyliczenia. W twojej odpowiedzi nie ma nic, co odpowiadałoby pierwotnemu pytaniu. Edytuj odpowiedź, aby odpowiedzieć na pytanie. – rothloup

+0

powyższy kod będzie rejestrował każdą nazwę wyliczeniową w wyliczeniu "kierunek". jak to teraz odpowiada na pytanie? – allanjwalter

+0

Być może powinieneś dodać trochę wyjaśnienia lub kodu, aby wskazać, że "kierunek" jest wyliczeniem, które rejestrujesz. Być może dla doświadczonego programisty jest oczywiste ze swojego kodu, ale taki koder nie opublikowałby tego pytania w pierwszej kolejności. Dodanie trochę wyjaśnienia pomoże ci wyjaśnić twoją odpowiedź i sprawi, że będzie ona bardziej przydatna dla każdego, kto się z nią spotka. – rothloup

Powiązane problemy