Durchschleifen von Enum-Werten

Lesezeit: 2 Minuten

Franks Benutzeravatar
Frank

Ist es möglich, Enum-Werte in Objective-C zu durchlaufen?

  • Retagged: Dies ist (AFAIK) eine reine C-Frage. Mit dem allgemeineren Tagging erhalten Sie mehr Antworten.

    – Brian Postow

    2. November 2009 um 19:45 Uhr

  • Es beantwortet auch die Frage für Leute, die in Obj-C danach suchen. Habe das Tag wieder hinzugefügt.

    – pbh101

    2. November 2009 um 19:47 Uhr

Benutzeravatar von Barry Wark
Barry Wark

Gegeben

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

Sie können die Elemente wie folgt iterieren:

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

Beachten Sie, dass dies die wirklich-nur-ein-int-Natur einer C-Enumeration offenbart. Insbesondere können Sie sehen, dass eine C-Enumeration nicht wirklich Typsicherheit bietet, da Sie anstelle eines Enum-Werts ein Int verwenden können und umgekehrt. Darüber hinaus hängt dies von der Deklarationsreihenfolge der Enum-Werte ab: zerbrechlich, um es gelinde auszudrücken. Siehe außerdem Chucks Kommentar; Wenn die Enum-Elemente nicht zusammenhängend sind (z. B. weil Sie explizite, nicht sequentielle Werte für einige Elemente angegeben haben), funktioniert dies überhaupt nicht. Huch.

  • Außerdem müssen alle Elemente in der Aufzählung zusammenhängend sein. Aber es ist das Beste, was Sie bekommen werden.

    – Chuck

    2. November 2009 um 19:23 Uhr

  • es erkennt Foo im for looo für mich nicht.

    – Frank

    2. November 2009 um 19:24 Uhr

  • Es ist ein reiner Nitpick, aber es ist Dinkel vice versa.

    – neu123456

    28. September 2011 um 16:02 Uhr

  • @MilesRout Es gibt tatsächlich eine minimale Zeichenänderung von 6 Zeichen. Da es sich um eine 2-Zeichen-Korrektur handelt, kann ich sie nicht beheben.

    – neu123456

    1. September 2013 um 16:13 Uhr

  • Beachten Sie, dass Sie Folgendes verwenden können, wenn die Werte nicht zusammenhängend sind, sondern eine Bitmaskenaufzählung: for (int i=1; i<=Last; i=i*2)

    – Karl

    27. August 2014 um 20:26 Uhr


Benutzeravatar von ennuikiller
Ennukiller

Wenn Sie enum wie folgt definiert ist:

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

Sie können es auf diese Weise durchlaufen:

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

  • Ich habe das noch nie gemacht, deshalb habe ich einige Fragen. Sollten es nicht Direction.East und Direction.South sein? Sollte die Bedingung nicht auch direction <= Direction.South sein? Ich habe das noch nie gemacht, ich versuche nicht, Sie zu korrigieren, ich würde es nur gerne lernen.

    – Jorge Israel Peña

    2. November 2009 um 18:28 Uhr

  • Gibt es einen besseren Weg, dies zu tun? Nur neugierig, aber es scheint, als wäre die Deklarationsreihenfolge der Enum-Werte bestenfalls zerbrechlich.

    – Ed S.

    2. November 2009 um 18:34 Uhr

  • @blaenk: Ich denke, Sie verwechseln Strukturen mit Aufzählungen.

    – pxl

    2. November 2009 um 18:37 Uhr

  • @Ed: Ja, das ist zerbrechlich, und nein, es gibt keinen besseren Weg. Es ist überhaupt nicht ratsam, dies zu tun.

    – Chuck

    2. November 2009 um 19:23 Uhr

  • Man könnte expliziter sein wie in enum Direction { East =1, West=2, North=3, South=4}; oder sogar enum Direction { East = 313, West, North, South}; aber es läuft alles auf dasselbe hinaus, außer dass die Nummerierung jedes Elements mehr Raum für Programmierfehler lässt. Am Ende scheint es mir so zerbrechlich oder nicht zerbrechlich zu sein wie jede const-Deklaration.

    – Elise van Looij

    3. November 2009 um 14:01 Uhr

Es ist ein bisschen umständlich (wie das gesamte Konzept also … eh …), aber wenn Sie dies mehrmals tun und in der Lage sein möchten, mit der Möglichkeit nicht zusammenhängender Aufzählungen umzugehen, Sie können ein (globales konstantes) Array erstellen und haben (um das Beispiel von ennukiller zu verwenden) Richtungen Richtungen[4] = {Osten, Westen, Norden, Süden}; und dann können Sie in Ihrer Schleife über Anweisungen sprechen[i] anstatt direkt über die Anweisungen selbst zu iterieren …

Wie gesagt, es ist hässlich, aber es ist etwas weniger zerbrechlich, denke ich …

  • Sieht gut für mich aus. Gibt es eine Möglichkeit, eine Art Makro hinzuzufügen, das automatisch C-Arrays für jeden von uns deklarierten Aufzählungstyp generiert?

    – ArtOfWarfare

    11. November 2012 um 16:40 Uhr

  • @ArtOfWarfare Ich benutze das die ganze Zeit: #define ENUM(type, ...) enum _##type { __VA_ARGS__ }; enum _##type type##s[] = { __VA_ARGS__ }, obwohl das nur für zusammenhängende funktioniert. Ich verwende keine nicht zusammenhängenden Aufzählungen, weil das für mich schlechtes Design signalisiert. Außerdem habe ich typedef struct _list List;, typedef enum _direction Direction überall in meinem C-Code, der dieses Makro verwendet, weshalb ich dem Typ das _ voranstelle. ENUM(direction, NORTH, EAST, SOUTH, WEST); gibt enum _direction { NORTH, EAST, SOUTH, WEST }; enum _direction directions = { NORTH, EAST, SOUTH, WEST }; Ich mag das.

    – Meilen Route

    31. August 2013 um 7:29 Uhr


Für nicht zusammenhängende Aufzählungen können Sie über gültige Werte iterieren, 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;
    }
}

Auf der Suche danach habe ich mir einfach die folgende Lösung ausgedacht, die meine eigenen Anforderungen erfüllt. Ich dachte, ich poste es hier für Leute, die etwas Ähnliches suchen.

Angenommen, ich habe eine Aufzählung.

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

Um es überschleifen zu können, definiere ich das folgende Präprozessor-Makro.

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

Dann verwende ich es in einer Schleife als solche:

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

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

Benutzeravatar von GhengisDon
GhengisDon

Die Länge (Anzahl der Elemente) einer beliebigen Aufzählung kann ermittelt werden, indem das Array von Namen in der Aufzählung 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;
}

Benutzeravatar der Community
Gemeinschaft

Ich mag, was ich von hier bekommen habe. Iteration over 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 weiterhin Aufzählungen hinzufügen und Ihre Schleifen nicht beeinflussen?

1402310cookie-checkDurchschleifen von Enum-Werten

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy