Dom: Switch Befehl will nicht so wie ich wohl will...

Hallo, hab ne kurze Frage:
Und zwar will ich ne simple Case Unterscheidung einer Zufallszahl machen.

Code folgt:

var zahl=2*Math.random()+1;
 var i=Math.round(zahl);
 alert(i);
 switch(i){
  case "1":
   document.write(textfeld1);
   break;
  case "2":
   document.write(textfeld2);
   break;
  case "3":
   document.write(textfeld3);
   break;
   default:
   alert("geht ned");
   break;
 }

das ganze steht in einer Funktion, liefert mir aber immer den default case zurück... Die Werte liegen immer zwischen 1 und 3... das scheint dem switch aber irgendwie egal zu sein.

Vielleicht bin ich blind... aber ich sehe den Fehler ned.

die textfelder wurden natürlich schon definiert...
also es geht nur um den switch

  1. Servus Dom (MS DOM? DOOM? Gutes Spiel...)!

    das ganze steht in einer Funktion, liefert mir aber immer den default case zurück...

    Verständlich, denn Du vergleichst ein Integer mit Strings. Ich weiß nicht, wie weit die Typautomatisierung in Javascript reicht, aber folgende Formulierung sollte zum Ziel führen:

    ...
    case 1:
       document.write(textfeld1);
       break;
    usw.

    Freundliche Grüße
    Stefano Albrecht

    --
    Sancta Simplicitas!
  2. Hallo,

    In den meisten Programmiersprachen gibt es einen fundamentalen Unterschied zwischen zwei Datentypen: Zeichenketten einerseits und Zahlen andererseits. (Es gibt natürlich noch andere wichtige Datentypen.) In JavaScript sind das eine Strings (vom String-Prototyp abgeleitete Objekte) und das andere Numbers (vom Number-Prototyp abgeleitete Objekte). Alle Methoden des Math-Objektes operieren mit Number-Werten.

    In JavaScript spielt diese Unterscheidung keine große Rolle, da der JavaScript-Interpreter den Datentyp automatisch umwandelt, sobald irgendwo ein String bzw. eine Number benötigt wird. In einigen anderen Sprachen muss man diese Umwandlung von Hand durchführen.

    Wenn du "1" notierst, erzeugst du jedenfalls einen String heraus, wenn du 1 notierst, eine Number.

    In deiner Variable zahl ist ein Number-Wert. In deiner switch-Fallunterscheidung vergleichst du diesen mit einem String:

    case "1" : ...
         ^^^ String

    Du müsstest also eine Number notieren:

    case 1 : ...
         ^ Number

    Das löst erst einmal dein Problem.

    Anzumerken wäre noch, dass das eine Ausnahme in JavaScript ist. Denn wie gesagt werden Strings automatisch in Numbers und Numbers automatisch in Strings umgewandelt, sofern nötig.

    Dieser logische Ausdruck mit Vergleichsoperator ergibt true:

    alert("1" == 1);

    Das demonstriert die automatische Umwandlung des linken String-Wertes in einen Number-Wert, damit er mit dem rechten Number-Wert vergleichbar ist (1 == 1 ergibt eben true).

    Gut, wieso funktioniert diese automatische Umwandlung nicht bei switch?

    Bei einer switch-Fallunterscheidung gibt es eine Besonderheit¹: Bei den Vergleichen wird nicht einfach überprüft, ob die Werte identisch sind. Es wird auch der Datentyp verglichen. Das entspricht dem strengen Vergleichsoperator ===.

    Den reduzierten Code

    var zahl = 1;  
    switch (zahl){  
       case "1" :  
         alert("1");  
    }
    

    könnte man folgendermaßen in eine if-Anweisung übersetzen:

    var zahl = 1;  
    if (zahl === "1") {  
       alert("1");  
    }
    

    Bei zahl === "1" wird nicht nur auf gleichen Wert geprüft - denn in dem Fall würde die automatische Typangleichung greifen -, sondern es wird auch auf gleichen Typ geprüft. Links steht eine Number, rechts ein String. Weil der Typ ungleich ist, ergibt der Ausdruck false.

    Deine ursprüngiche switch-Anweisungen könnte man zur Veranschaulichung in verschachtelte if-Abfragen übersetzen:

    var zahl = 1;  
    if (zahl !== "1") {  
     if (zahl !== "2") {  
      if (zahl !== "3") {  
       alert("geht ned");  
      } else {  
       document.write(textfeld3);  
      }  
     } else {  
      document.write(textfeld2);  
     }  
    } else {  
     document.write(textfeld1);  
    }  
    
    

    In ECMAScript, dem Standard, der die Abarbeitung der switch-Struktur definiert, ist dieser Algorithmus definiert. Der Operator !== ist einfach der negativierte ===-Operator. Der Ausdruck x !== y bedeutet »x und y sind nicht wertegleich *oder* nicht typengleich«.

    Somit zeigt sich, warum der Interpreter in den Zweig mit alert("geht ned") kommt: Die Number wird immer mit Strings verglichen und dabei wird auf gleichen Typ geachtet. Das geht schief.

    Mathias

    --
    ¹ Siehe ECMAScript
  3. n'Abend,

    Und zwar will ich ne simple Case Unterscheidung einer Zufallszahl machen.

    ja, dann tu das doch auch.
    Ich verstehe gar nicht, wie manche Neulinge immer wieder auf die Idee kommen, mit einem String zu vergleichen, wenn sie eigentlich mit Zahlen hantieren - das gleiche Thema hatten wir doch erst gestern.

    var i=Math.round(zahl);

    Also ist i hier eindeutig eine Zahl.

    switch(i){
      case "1":
      case "2":
      case "3":

    Warum prüfst du dann auf Strings?

    So long,
     Martin

    --
    Ich stehe eigentlich gern früh auf.
    Außer morgens.
  4. Hello out there!

    var zahl=2*Math.random()+1;
    var i=Math.round(zahl);

    Willst du das wirklich?

    Sei x deine Zufallszahl, 0 ≤ x < 1. Dann gibt es folgende Fälle:

    0 ≤    x   < 0.25 │ 0.25 ≤    x   < 0.75 │ 0.75 ≤    x   < 1
    0 ≤   2x   < 0.5  │ 0.5  ≤   2x   < 1.5  │ 1.5  ≤   2x   < 2
    1 ≤ 2x + 1 < 1.5  │ 1.5  ≤ 2x + 1 < 2.5  │ 2.5  ≤ 2x + 1 < 3
    ──────────────────┼──────────────────────┼──────────────────
         i = 1        │         i = 2        │         i = 3
      p(1) = 1/4      │      p(2) = 1/2      │      p(3) = 1/4

    Wie du siehst, ist das Intervall für x, für das i = 2 wird, doppelt so breit wie die anderen beiden Intervalle, die Wahrscheinlichkeit des Auftretens von i = 2 ist also doppelt so hoch wie die des Auftretens von i = 1 und i = 3.

    Willst du Gleichverteilung erreichen, darfst du nicht Math.round() verwenden, sondern Math.floor():

    var i = Math.floor(3 * Math.random() + 1);

    0 ≤    x   < 1/3  │  1/3 ≤    x   < 2/3  │  2/3 ≤    x   < 1
    0 ≤   3x   < 1    │    1 ≤   3x   < 2    │    2 ≤   3x   < 3
    1 ≤ 3x + 1 < 2    │    2 ≤ 3x + 1 < 3    │    3 ≤ 3x + 1 < 4
    ──────────────────┼──────────────────────┼──────────────────
         i = 1        │         i = 2        │         i = 3
      p(1) = 1/3      │      p(2) = 1/3      │      p(3) = 1/3

    See ya up the road,
    Gunnar

    --
    “Remember, in the end, nobody wins unless everybody wins.” (Bruce Springsteen)
    1. Hallo Gunnar Bittersmann,

      zum Nachrechnen: http://www.j-berkemeier.de/test/zuftest.html

      Gruß, Jürgen

      1. Hello out there!

        zum Nachrechnen: http://www.j-berkemeier.de/test/zuftest.html

        zum Nachlesen: http://forum.de.selfhtml.org/archiv/2004/2/t71712/#m412959 ;-)

        Den hab ich gefunden, nachdem ich mir http://forum.de.selfhtml.org/archiv/2005/1/t98169/#m598387 ff. nochmal aus’m Archiv rausgesucht hatte.

        See ya up the road,
        Gunnar

        --
        “Remember, in the end, nobody wins unless everybody wins.” (Bruce Springsteen)