wake-up-neo.com

durchlaufen der enum-Werte

Ist es möglich, die Aufzählungswerte in Objective-C durchzugehen?

32
Frank

Gegeben

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

sie können die Elemente wie folgt durchlaufen:

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

Beachten Sie, dass dies die wirklich nur ein int-Natur eines C-Enums darstellt. Insbesondere können Sie sehen, dass eine C-Enumeration keine Typensicherheit bietet, da Sie anstelle eines Enumerationswerts ein int verwenden können und umgekehrt. Außerdem hängt dies von der Deklarationsreihenfolge der Aufzählungswerte ab: fragil gelinde gesagt. Siehe auch den Kommentar von Chuck. Wenn die Aufzählungselemente nicht zusammenhängend sind (z. B. weil Sie für einige Elemente explizite, nicht sequentielle Werte angegeben haben), funktioniert dies überhaupt nicht. Yikes.

38
Barry Wark

Es ist ein bisschen kludge (wie das gesamte Konzept so ... eh ...), aber wenn Sie dies mehrmals tun werden und Sie mit der Möglichkeit eines nicht zusammenhängenden Enums umgehen wollen, Sie können ein (globales konstantes) Array erstellen und (um das Beispiel von ennukiller zu verwenden) Richtungen [4] = {Ost, West, Nord, Süd}; und dann können Sie in Ihrer Schleife über Richtungen [i] sprechen. anstatt direkt über die Richtungen zu iterieren ... 

Wie gesagt, es ist hässlich, aber ich denke, es ist etwas weniger fragil ...

8
Brian Postow

Wenn Ihre Aufzählung wie folgt definiert ist:

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

Sie können es so durchlaufen:

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

Auf dieser Suche habe ich mir die folgende Lösung zusammengestellt, die meine eigenen Anforderungen erfüllte. Ich dachte, ich würde es hier für Leute posten, die etwas Ähnliches suchen.

Sagen Sie, ich habe eine Aufzählung.

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

Um darüber schleifen zu können, definiere ich das folgende Präprozessor-Makro.

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

Dann verwende ich es innerhalb einer Schleife als solche:

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

Dadurch wird die Logik für das Iterieren an einer Stelle (das Makro) platziert, was die Wartbarkeit des Codes erhöht. 

5
CloakedEddy

Für nicht zusammenhängende Enums können Sie gültige Werte durchlaufen, indem Sie Folgendes tun:

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

Die Länge (Anzahl der Elemente) einer Aufzählung kann ermittelt werden, indem das Array mit Namen in der Enumeration abgerufen und die Länge des Arrays verwendet wird. Verwenden Sie die GetNames-Methode von Enum. Enum.GetNames (EnumType) .Length.

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

Mir gefällt, was ich von hier bekommen habe Iteration über Enum in Objective C?

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


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

auf diese Weise können Sie später weitere Aufzählungen hinzufügen und Ihre Loops nicht beeinflussen.

1
yeahdixon

Ich hasse es, mein Enum mit einem "Last" -Eintrag zu beschmutzen (und der begleitenden Anmerkung, dass es nicht verwendet werden sollte und dass es immer aufbewahrt werden muss, nun ja, zuletzt) ​​und nur einen Weg dahinter gefunden hat den letzten Enum-Eintrag als geheimes "letztes" zu verwenden, was mich wieder icky fühlt);.

Wenn Sie Ihr Enum mit X Macros definieren, können Sie ganz einfach die Anzahl der Elemente in Ihrem Enum ermitteln. Sehen Sie den Link FMI an, wenn Sie diesen Ansatz verwenden könnten. Um es kurz zu halten, sieht es so aus:

#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

Wenn das Obige für Sie nicht funktioniert, weil Sie C++ verwenden, sollte Folgendes Folgendes sein: :

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

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