Eric Teubert: SWITCH-Kontrolle

Hiho,

Hier
http://www.selfphp.net/selfphp/navigation/index.html
konnte ich nichts zu meinem Problem finden, deshalb wende ich mich an euch. Und zwar soll das ganze dann etwa so aussehen:

switch ($charexp){
  case 100   :$lvlup2=1   ;break;
  case 500   :$lvlup2=2   ;break;
  case 1000  :$lvlup2=3   ;break;
  case 1500  :$lvlup2=4   ;break;
  case 2000  :$lvlup2=5   ;break;
  case 2500  :$lvlup2=6   ;break;
  case 3000  :$lvlup2=7   ;break;
  case 3500  :$lvlup2=8   ;break;
  case 4000  :$lvlup2=9   ;break;
  case 4500  :$lvlup2=10  ;break;
 }

Nur soll nicht die einzelne Zahl abgefragt werden, sondern der Bereich davor, also praktisch im ersten Fall 0-99, im zweiten 100-499.
Sinngemäß so:

switch ($charexp){
  case <100   :$lvlup2=1   ;break;
  case <500   :$lvlup2=2   ;break;
  case <1000  :$lvlup2=3   ;break;
  case <1500  :$lvlup2=4   ;break;
  case <2000  :$lvlup2=5   ;break;
  case <2500  :$lvlup2=6   ;break;
  case <3000  :$lvlup2=7   ;break;
  case <3500  :$lvlup2=8   ;break;
  case <4000  :$lvlup2=9   ;break;
  case <4500  :$lvlup2=10  ;break;
 }

Nur geht das ja nicht und ich möchte ungern 4500 case-Zeilen schreiben ...
Ich hoffe mal, es gibt dafür eine Lösung.

Danke im Voraus

Eric

  1. Moin,

    Nur geht das ja nicht und ich möchte ungern 4500 case-Zeilen schreiben ...
    Ich hoffe mal, es gibt dafür eine Lösung.

    if($charexp<100) $lvlup=1; else $lvlup = floor($charexp/500)+1; ?

    --
    Henryk Plötz
    Grüße aus Berlin
    ~~~~~~~~ Un-CDs, nein danke! http://www.heise.de/ct/cd-register/ ~~~~~~~~
    ~~ Help Microsoft fight software piracy: Give Linux to a friend today! ~~
    1. Moin,

      if($charexp<100) $lvlup=1; else $lvlup = floor($charexp/500)+1; ?

      Ähm, der aufmerksame Leser hat sicher bemerkt dass es ceil statt floor heissen müsste.

      --
      Henryk Plötz
      Grüße aus Berlin
      ~~~~~~~~ Un-CDs, nein danke! http://www.heise.de/ct/cd-register/ ~~~~~~~~
      ~~ Help Microsoft fight software piracy: Give Linux to a friend today! ~~
      1. if($charexp<100) $lvlup=1; else $lvlup = ceil($charexp/500)+1; ?

        Ja klar, mit ner IF-Anweisung ... nur ... das sind dann später 80 Stück und da hätte ich's ebend ganz gern mit SWITCH gemacht - wenn das geht.

        Mal seh'n, ob noch jemand anderes ne Idee hat.

        1. Moin,

          Mal seh'n, ob noch jemand anderes ne Idee hat.

          Wie geht's denn weiter? case 5000: $lvlup=11; break; ... ? ;-) Will sagen: Gibt es denn wirklich _gar keine_ Regelmäßigkeit die du zur Berechnung ranziehen kannst?

          Du kannst dir ja noch mit einer Schleife behelfen, das ist dann ggbf. etwas langsamer.

          $a = Array(0, 100, 500, 1000, 1500, 2000, 2500, ....);
          $lvlup = 0; while($a[++$lvlup]<=$charexp && $lvlup<10);

          --
          Henryk Plötz
          Grüße aus Berlin
          ~~~~~~~~ Un-CDs, nein danke! http://www.heise.de/ct/cd-register/ ~~~~~~~~
          ~~ Help Microsoft fight software piracy: Give Linux to a friend today! ~~
          1. Wie geht's denn weiter? case 5000: $lvlup=11; break; ... ? ;-) Will sagen: Gibt es denn wirklich _gar keine_ Regelmäßigkeit die du zur Berechnung ranziehen kannst?

            Hmja, genau das ist das Problem. Derzeit erscheint es noch recht regelmäßig aber das sind nur "Testwerte", die später keiner Regelmäßigkeit mehr folgen werden.

            Du kannst dir ja noch mit einer Schleife behelfen, das ist dann ggbf. etwas langsamer.

            $a = Array(0, 100, 500, 1000, 1500, 2000, 2500, ....);
            $lvlup = 0; while($a[++$lvlup]<=$charexp && $lvlup<10);

            Arrays hmmm hmmm ... ja mal rumprobieren ...
            Aber gibt es denn keine Möglichkeit, per SWITCH mehr als nur eine einzelne Zahl eingebe?

            Oder ... da kommt mir gerade eine Idee: könnte ich nicht vorher Variablen mit einem Array füllen ( z.B. mit 1-99 ) und diese dann anstatt der Zahl hinter case setzen? also in etwa so:

            $a=range(1,99);
            $b=range(100,499);

            switch ($charexp){
              case $a   :$lvlup2=1   ;break;
              case $b   :$lvlup2=2   ;break;
            }

            Wäre das vielleicht eine Lösung?

            1. $a=range(1,99);
              $b=range(100,499);

              switch ($charexp){
                case $a   :$lvlup2=1   ;break;
                case $b   :$lvlup2=2   ;break;
              }

              Wäre das vielleicht eine Lösung?

              Hm, irgendwie hat der damit

              $a=range(1,99);
              $b=range(100,499);

              ein Problem.
              Wenn ich die Variablen Textweise per Echo ausgebe, steht auch nur "Array" da. Was mache ich falsch?

            2. Moin,

              Du kannst dir ja noch mit einer Schleife behelfen, das ist dann ggbf. etwas langsamer.

              $a = Array(0, 100, 500, 1000, 1500, 2000, 2500, ....);
              $lvlup = 0; while($a[++$lvlup]<=$charexp && $lvlup<10);

              Arrays hmmm hmmm ... ja mal rumprobieren ...
              Aber gibt es denn keine Möglichkeit, per SWITCH mehr als nur eine einzelne Zahl eingebe?

              Klar: case 1: case 2: case 3: $lvlup = 1; break; case 4: case 5: ....

              Was genau gefällt dir an obiger Lösung nicht? Es dürfte die einfachste Variante sein, wenn du nicht alles ausschreiben willst. if($charexp < 100) ...; else if($charexp < 500) ...; ... willst du ja offenbar explizit nicht. (Warum nicht? Gerüchten zufolge kann man sich auch schnell ein kleines Skript schreiben welches einem fix diese if-Klauseln erzeugt. *schauder* Man könnte das sogar als weitere 'Lösung' ansehen und dann eval verwenden. Aber eval ist bekanntlich böse.)

              Oder ... da kommt mir gerade eine Idee: könnte ich nicht vorher Variablen mit einem Array füllen ( z.B. mit 1-99 ) und diese dann anstatt der Zahl hinter case setzen?

              Klar, dann trifft der case halt zu wenn $charexp ein Array mit den Zahlen von 1 bis 99 ist. Das ist glaube ich nicht ganz was du willst.

              Wäre das vielleicht eine Lösung?

              Natürlich, nur halt für ein anderes Problem.

              --
              Henryk Plötz
              Grüße aus Berlin
              ~~~~~~~~ Un-CDs, nein danke! http://www.heise.de/ct/cd-register/ ~~~~~~~~
              ~~ Help Microsoft fight software piracy: Give Linux to a friend today! ~~
              1. Was genau gefällt dir an obiger Lösung nicht? Es dürfte die einfachste Variante sein, wenn du nicht alles ausschreiben willst. if($charexp < 100) ...; else if($charexp < 500) ...; ... willst du ja offenbar explizit nicht. (Warum nicht? Gerüchten zufolge kann man sich auch schnell ein kleines Skript schreiben welches einem fix diese if-Klauseln erzeugt. *schauder* Man könnte das sogar als weitere 'Lösung' ansehen und dann eval verwenden. Aber eval ist bekanntlich böse.)

                Hmja na gut, dann werde ich das jetzt mal per if-Anweisungen probieren.
                Die 2 Zeilen von dir

                $a = Array(0, 100, 500, 1000, 1500, 2000, 2500, ....);
                $lvlup = 0; while($a[++$lvlup]<=$charexp && $lvlup<10);

                verstehe ich nicht ganz, da hinter while nur eine Bedingung steht, aber nicht, was ausgeführt werden soll ... ?
                Naja, ich versuch's mit den "einfachen" Anweisungen.

                Danke

                1. Moin,

                  $a = Array(0, 100, 500, 1000, 1500, 2000, 2500, ....);
                  $lvlup = 0; while($a[++$lvlup]<=$charexp && $lvlup<10);

                  verstehe ich nicht ganz, da hinter while nur eine Bedingung steht, aber nicht, was ausgeführt werden soll ... ?

                  Dann sag das doch und ignoriere es nicht einfach.

                  Das while braucht an der Stelle keinen Körper (bzw. es hat einen Leeren), da nichts weiter ausgeführt werden muss. Die einzige Aktion ist die Inkrementierung von $lvlup die aber schon beim Auswerten der Bedingung geschieht. Man könnte das äquivalent auch länger als do { ++$lvlup; } while ($a[$lvlup]<=$charexp && $lvlup<10); schreiben, aber das ist ..nunja.. länger.

                  --
                  Henryk Plötz
                  Grüße aus Berlin
                  ~~~~~~~~ Un-CDs, nein danke! http://www.heise.de/ct/cd-register/ ~~~~~~~~
                  ~~ Help Microsoft fight software piracy: Give Linux to a friend today! ~~
                  1. do { ++$lvlup; } while ($a[$lvlup]<=$charexp && $lvlup<10);

                    Ok, das verstehe ich ;)
                    Aber habe es jetzt mit den If-Anweisungen gelöst. Werde mir die while-Geschichte hier nochmal anschaun, weil es wohl effektiver ist aber das Problem an sich ist ja gelöst.

                    Vielen Dank

                    Eric

                2. Huhu Eric

                  Die 2 Zeilen von dir

                  $a = Array(0, 100, 500, 1000, 1500, 2000, 2500, ....);
                  $lvlup = 0; while($a[++$lvlup]<=$charexp && $lvlup<10);

                  verstehe ich nicht ganz, da hinter while nur eine Bedingung steht, aber nicht, was ausgeführt werden soll ... ?

                  Hier mal etwas ausführlicher

                  $a = Array(0, 100, 500, 1000, 1500, 2000, 2500, ....);
                  $lvlup = 0;

                  while( $a[$lvlup] <= $charexp && $lvlup<10){
                   $lvlup++;
                  }

                  Diese Lösungsvariante ist sehr elegant :-)
                  Henryk benutzt dabei den "pre increment operator".
                  http://www.php.net/manual/en/language.operators.increment.php

                  Das sieht kryptischer aus als es ist.
                  Was Dich verwirrt ist die Tatsache das dieses while-Konstrukt
                  scheinbar keine Anweisung ausführt.
                  Diese ist aber im Schleifen Kopf integriert.

                  In Worten ungefähr

                  Erhöhe den Zähler lvlup um eins und prüfe ob das zugehörige Array-Element <= $charexp ist.
                  Wenn ja prüfe zusätzlich ob der Zähler < 10 ist.
                  (Das ist eine Notausstiegsklausel damit die While-Schleife in jedem Fall beendet wird.)
                  Das wird solange gemacht bis die Bedingung nicht mehr zutrifft.
                  Dann enthält der Zähler lvlup den gewünschten Wert.

                  Viele Grüße

                  lulu

                  --
                  bythewaythewebsuxgoofflineandenjoytheday
  2. Sinngemäß so:

    switch (true){
      case $charexp<100   :$lvlup2=1   ;break;
      case $charexp<500   :$lvlup2=2   ;break;
      case $charexp<1000  :$lvlup2=3   ;break;
      case $charexp<1500  :$lvlup2=4   ;break;
      case $charexp<2000  :$lvlup2=5   ;break;
      case $charexp<2500  :$lvlup2=6   ;break;
      case $charexp<3000  :$lvlup2=7   ;break;
      case $charexp<3500  :$lvlup2=8   ;break;
      case $charexp<4000  :$lvlup2=9   ;break;
      case $charexp<4500  :$lvlup2=10  ;break;
     }