Wechseln Sie die Anweisung für mehrere Fälle in JavaScript

767

Ich benötige mehrere Fälle in der switch-Anweisung in JavaScript. So etwas wie:

switch (varName)
{
   case "afshin", "saeed", "larry": 
       alert('Hey');
       break;

   default: 
       alert('Default case');
       break;
}

Wie kann ich das machen? Wenn es in JavaScript keine Möglichkeit gibt, so etwas zu tun, möchte ich eine alternative Lösung kennen, die auch dem DRY-Konzept folgt .

Afshin Mehrabani
quelle
5
An denjenigen, der dafür gestimmt hat, diese Frage zu schließen. Es ist mehr als 5 Jahre alt und hat eine vollständige Antwort - warum die enge Abstimmung?
Surfmuggle
@surfmuggle, da es nicht notwendig ist, weitere Antworten hinzuzufügen.
Afshin Mehrabani
7
@AfshinMehrabani vielleicht kann es geschützt werden, nicht geschlossen?
Evolutionxbox

Antworten:

1508

Verwenden Sie die Fall-Through-Funktion der switchAnweisung. Ein übereinstimmender Fall wird ausgeführt, bis ein break(oder das Ende der switchAnweisung) gefunden wird. Sie können ihn also wie folgt schreiben:

switch (varName)
{
   case "afshin":
   case "saeed":
   case "larry": 
       alert('Hey');
       break;

   default: 
       alert('Default case');
}
kennytm
quelle
2
Irgendwie funktioniert es für mich in Chrome, in der Javascript-Konsole: switch('10') { case 1, '10': console.log('ok') }Druckeok
Nafg
8
@nafg: Versuchen Sie es switch(1). Das Etikett hier ist nur ein Kommaausdruck.
Kennytm
4
@Barney Nein, ohne die Pause kannst du zum nächsten Fall durchfallen.
Seiyria
1
@Seiyira per Definition gibt es keinen nächsten Fall nach dem letzten. Außerdem ist es eine Standardeinstellung.
Barney
101

Dies funktioniert in normalem JavaScript

function theTest(val) {
  var answer = "";
  switch( val ) {
    case 1: case 2: case 3:
      answer = "Low";
      break;
    case 4: case 5: case 6:
      answer = "Mid";
      break;
    case 7: case 8: case 9:
      answer = "High";
      break;
    default:
      answer = "Massive or Tiny?";
  } 
  return answer;  
}

theTest(9);

Prost.

Rob Welan
quelle
13
@believesInSanta es ist buchstäblich nur normaler Fallfall mit seltsamer Formatierung (Leerzeichen anstelle von Zeilenumbrüchen)
Mihail Malostanidis
42

Hier ist ein anderer Ansatz, bei dem die switchAussage insgesamt vermieden wird :

var cases = {
  afshin: function() { alert('hey'); },
  _default: function() { alert('default'); }
};
cases.larry = cases.saeed = cases.afshin;

cases[ varName ] ? cases[ varName ]() : cases._default();
elclanrs
quelle
5
Ich bevorzuge definitiv diese Version. Durchfallen ist eine fehleranfällige Funktion von switch ... case. Es ist zu leicht, eine breakAussage zu vergessen , und wenn Sie absichtlich durchfallen, können diese vergessenen breakAussagen sehr schwer zu erkennen sein. Diese Methode zur Methodensuche bietet auch viele großartige Funktionen, die switch ... casefehlen, wie z. B. die dynamische Erweiterbarkeit oder die Möglichkeit, das Objekt vollständig zu ersetzen, um die Modusumschaltung durchzuführen. Es ist auch einfacher, sauber organisiert zu bleiben, und kann zu besser wartbarem Code führen. Siehe ericleads.com/2012/12/switch-case-considered-harmful
Eric Elliott
31
Ich füge immer einen Kommentar //fallthroughstatt , breakwenn ich das absichtlich unterlassen break. Das hilft zu erkennen, wann es ein Fehler ist und wann es beabsichtigt ist.
Mnebuerquo
18
Intuitiver Ansatz. Aus Gründen der Lesbarkeit würde ich jedoch empfehlen, die native switch-Anweisung zu verwenden.
Kontaktmatt
39
Man kann immer das linke Ohr kratzen, indem man die rechte Hand durch den Nacken führt ... (Entschuldigung für mein Englisch, ich meine: "Man kann die Dinge immer so kompliziert wie möglich machen ... in diesem Fall ohne die switch-Anweisung zugunsten dieser komplizierten Lösung scheint nicht das Richtige zu sein ...)
Clint Eastwood
25
Ich bin wirklich erstaunt, wie das 34 Stimmen bekommen hat. In Bezug auf Lesbarkeit und Wartbarkeit ist dies absolut schrecklich. Wenn ich sehen möchte, welche Bedingungen etwas auslösen, ist eine case-Anweisung unglaublich einfach und leicht zu erkennen, wenn man sich die Etiketten ansieht. Andererseits würde Ihre Version erfordern, dass jemand so ziemlich jede einzelne Zeile liest und sieht, was Sie wo zugewiesen haben. Dies wird noch schlimmer, je mehr Fälle Sie abgleichen möchten.
Michael
21

In Javascript müssen wir different case without break inbetweenwie folgt definieren, um mehrere Fälle in einem Switch zuzuweisen :

   <script>
      function checkHere(varName){
        switch (varName)
           {
           case "saeed":
           case "larry":
           case "afshin":
                alert('Hey');
                break;
          case "ss":
               alert('ss');
               break;
         default:
               alert('Default case');
               break;
       }
      }
     </script>

Bitte sehen Sie das Beispiel, klicken Sie auf den Link

Er. Anurag Jain
quelle
5
Es ist eine übliche Technik in einer Vielzahl von Sprachen, die nicht an JS gebunden ist
drAlberT
13

Wenn Sie ES6 verwenden, können Sie Folgendes tun:

if (['afshin', 'saeed', 'larry'].includes(varName)) {
   alert('Hey');
} else {
   alert('Default case');
}

Für frühere Versionen von JavaScript können Sie Folgendes tun:

if (['afshin', 'saeed', 'larry'].indexOf(varName) !== -1) {
   alert('Hey');
} else {
   alert('Default case');
}

Beachten Sie, dass dies in älteren IE-Browsern nicht funktioniert, Sie die Dinge jedoch recht einfach reparieren können. Weitere Informationen finden Sie in der Frage , ob die Zeichenfolge in der Liste in Javascript enthalten ist.

ErikE
quelle
Was ist der Vorteil davon gegenüber einem Schalter?
Bryce Snyder
@BryceSnyder der Unterschied zwischen einem Ausdruck und einer Anweisung? Weniger tippen? Weniger vertikale Linien verbraucht? Größere Ausdruckskraft durch Prägnanz und Repräsentationsdichte? Bessere Semantik durch das includesWort? Treffen Sie Ihre Wahl.
ErikE
7

Im Knoten scheint es Ihnen erlaubt zu sein, dies zu tun:

data = "10";
switch(data){
case "1": case "2": case "3": //put multiple cases on the same line to save vertical space.
   console.log("small"); break;
case "10": case "11": case "12":
   console.log("large"); break;
default:
   console.log("strange");
   break;
}

Dies führt in einigen Fällen zu einem viel kompakteren Code.

Automatico
quelle
1
Ich denke, die Syntax ist die gleiche wie in anderen JS-Umgebungen.
Afshin Mehrabani
1
@AfshinMehrabani Es könnte sein, ich habe es nur im Kontext von nodejs getestet.
Automatico
Ja. Ich mag es, vertikalen Raum zu sparen!
Kanal
7

Wenn Sie Stefanos Antwort hinzufügen und klarstellen, können Sie Ausdrücke verwenden, um die Werte für die Bedingungen im Schalter dinamisch festzulegen, z.

var i = 3
switch (i) {
    case ((i>=0 && i<=5)?i:-1): console.log('0-5'); break;
    case 6: console.log('6');
}

In Ihrem Problem könnten Sie also Folgendes tun:

var varName = "afshin"
switch (varName) {
    case (["afshin", "saeed", "larry"].indexOf(varName)+1 && varName):
      console.log("hey");
      break;

    default:
      console.log('Default case');
}

obwohl nicht so viel trocken ..

Z. Khullah
quelle
Noch nicht getestet, aber es wäre interessant, varNameden case-Ausdruck zu ändern. Erwarten Sie, dass varName zwischengespeichert wird.
Valen
5

Sie können die ‚Verwendung in ‘ Operator ...
verlässt sich auf das Objekt / Hash - Aufruf ...
so seine so schnell wie Javascript sein kann ...

// assuming you have defined functions f(), g(a) and h(a,b) 
// somewhere in your code
// you can define them inside the object but... 
// the code becomes hard to read, I prefer this way

o = { f1:f, f2:g, f3:h };

// if you use "STATIC" code can do:
o['f3']( p1, p2 )

// if your code is someway "DYNAMIC", to prevent false invocations
// m brings the function/method to be invoked (f1, f2, f3)
// and you can rely on arguments[] to solve any parameter problems
if ( m in o ) o[m]()

Viel Spaß, ZEE

ZEE
quelle
Wie hängt das mit dem Wechsel zusammen? kannst du es klarstellen
Z. Khullah
Warum sollten Sie Ihren Code "schwer lesbar" machen wollen? Das erste, was mir als Programmierer gesagt wurde, war, Code mit der Einstellung zu schreiben, dass die nächste Person, die Ihren Code liest, eine Axt mit Serienmörder ist und er es hasst, Code nicht verstehen zu können.
MattE
Hallo Matt ... ich präsentiere es hier als Proof of Concept ... trotzdem bietet Ihnen dieses Formular mehr Funktionalität und Flexibilität ... und Sie verwenden es nur, wenn Sie wollen ... oder wenn Sie eine Einschränkung in Ihrem finden übliche Form, Dinge zu tun ... betrachten Sie ir als ein weiteres Werkzeug in Ihrer Programmierer-Toolbox ...
ZEE
5

Ich benutze so:

switch (true){
     case /Pressure/.test(sensor):{
        console.log('Its pressure!');
        break;
     }
     case /Temperature/.test(sensor):{
        console.log('Its temperature!');
        break;
     }
}
Sergey Volkov
quelle
Sie müssen die gFlagge nicht verwenden, da Sie die regulären Ausdrücke nur einmal verwenden und wegwerfen. Wenn Sie sie außerhalb der Funktion gbelassen, würde Ihnen das Flag schaden , wenn Sie versuchen, bei nachfolgenden .test(s von einem Nicht-0-Index abzugleichen. Ich habe auch einen Tippfehler behoben, bei dem der Schalterfall sensorvariabel und nicht truekonstant war, um boolesche Ausdrücke abzugleichen. Siehe die Bearbeitung.
Mihail Malostanidis
Ich habe dieses Format verwendet, um gegen Dateitypen zu testen. Beispiel:case /officedocument/.test(type) && /presentation/.test(type): iconClass = "far fa-file-powerpoint red"; break;
tbone849
4

Es hängt davon ab, ob. Switch wertet einmal und nur einmal aus. Bei einem Match werden alle nachfolgenden Fallaussagen bis zum "Break" ausgelöst, unabhängig davon, was der Fall sagt.

var onlyMen = true;
var onlyWomen = false;
var onlyAdults = false;
 
 (function(){
   switch (true){
     case onlyMen:
       console.log ('onlymen');
     case onlyWomen:
       console.log ('onlyWomen');
     case onlyAdults:
       console.log ('onlyAdults');
       break;
     default:
       console.log('default');
   }
})(); // returns onlymen onlywomen onlyadults
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>

Ronnie Royston
quelle
3

Ich mag dies für Klarheit und DRY-Syntax.

varName = "larry";

switch (true)
{
    case ["afshin", "saeed", "larry"].includes(varName) :
       alert('Hey');
       break;

    default: 
       alert('Default case');

}
Kyle Dudley
quelle
2

Ich kann sehen, dass es hier viele gute Antworten gibt, aber was passiert, wenn wir mehr als 10 Fälle überprüfen müssen? Hier ist mein eigener Ansatz:

 function isAccessible(varName){
     let accessDenied = ['Liam','Noah','William','James','Logan','Benjamin',
                        'Mason','Elijah','Oliver','Jacob','Daniel','Lucas'];
      switch (varName) {
         case (accessDenied.includes(varName)?varName:null): 
             return 'Access Denied!';
         default:
           return 'Access Allowed.';
       }
    }

    console.log(isAccessible('Liam'));
Aravinda Meewalaarachchi
quelle
1
Dies ist ein Missbrauch der switch-Anweisung. Ist einfach if (accessDenied.includes(varName)) return 'Access Denied!'; return 'Access Allowed.'mehr als genug.
Mihail Malostanidis
2

Das Problem bei den obigen Ansätzen besteht darin, dass Sie die verschiedenen cases jedes Mal wiederholen müssen, wenn Sie die Funktion aufrufen, die die hat switch. Eine robustere Lösung besteht darin, eine Karte oder ein Wörterbuch zu haben .

Hier ein Beispiel

// the Map, divided by concepts
var dictionary = {
  timePeriod: {
    'month': [1, 'monthly', 'mensal', 'mês'],
    'twoMonths': [2, 'two months', '2 motnhs', 'bimestral', 'bimestre'],
    'trimester': [3, 'trimesterly', 'quarterly', 'trimestral'],
    'semester': [4, 'semesterly', 'semestral', 'halfyearly'],
    'year': [5, 'yearly', 'anual', 'ano']
  },
  distance: {
    'km': [1, 'kms', 'kilometre', 'kilometers', 'kilometres'],
    'mile': [2, 'mi', 'miles'],
    'nordicMile': [3, 'nordic mile', 'mil(10km)', 'scandinavian mile']
  },
  fuelAmount: {
    'ltr': [1, 'l', 'litre', 'Litre', 'liter', 'Liter'],
    'gal(imp)': [2, 'imp gallon', 'imperial gal', 'gal(UK)'],
    'gal(US)': [3, 'US gallon', 'US gal'],
    'kWh': [4, 'KWH']
  }
};

//this function maps every input to a certain defined value
function mapUnit (concept, value) {
  for (var key in dictionary[concept]) {
    if (key === value || 
      dictionary[concept][key].indexOf(value) !== -1) {
      return key
    }
  }
  throw Error('Uknown "'+value+'" for "'+concept+'"')
}

//you would use it simply like this
mapUnit("fuelAmount", "ltr") // => ltr
mapUnit("fuelAmount", "US gal") // => gal(US)
mapUnit("fuelAmount", 3) // => gal(US)
mapUnit("distance", "kilometre") // => km
  
//now you can use the switch statement safely without the need 
//to repeat the combinations every time you call the switch
var foo = 'monthly'
switch (mapUnit ('timePeriod', foo)) {
  case 'month': 
    console.log('month')
    break
  case 'twoMonths': 
    console.log('twoMonths')
    break
  case 'trimester': 
    console.log('trimester')
    break
  case 'semester': 
    console.log('semester')
    break
  case 'year': 
    console.log('year')
    break
  default:
    throw Error('error')
}

João Pimentel Ferreira
quelle
1

Du kannst das:

alert([
  "afshin", 
  "saeed", 
  "larry",
  "sasha",
  "boby",
  "jhon",
  "anna",
  // ...
].includes(varName)? 'Hey' : 'Default case')

oder nur eine einzige Codezeile:

alert(["afshin", "saeed", "larry",...].includes(varName)? 'Hey' : 'Default case')

eine kleine Verbesserung gegenüber ErikEs Antwort

Dedy Abdillah
quelle
1

Für jeden, der mit einem ähnlichen Problem hierher kam, das ich nach wochenlangem Codieren und einem Burnout hatte, war meine Situation ungefähr so:

switch (text) {
  case SOME_CONSTANT || ANOTHER_CONSTANT:
    console.log('Case 1 entered');

  break;

  case THIRD_CONSTANT || FINAL_CONSTANT:
    console.log('Case 2 entered');

  break;

  default:
    console.log('Default entered');
}

Immer der defaultFall eingegeben. Wenn Sie auf ein ähnliches Problem mit Switch-Anweisungen in mehreren Fällen stoßen, suchen Sie nach:

switch (text) {
  case SOME_CONSTANT:
  case ANOTHER_CONSTANT:
    console.log('Case 1 entered');

  break;

  case THIRD_CONSTANT:
  case FINAL_CONSTANT:
    console.log('Case 2 entered');

  break;

  default:
    console.log('Default entered');
}

Ich hoffe, das hilft jemandem. Ich habe mir die Haare ausgezogen, bevor ich mich daran erinnerte, das Schaltergehäuse genauso zu verwenden, wie ich es in meinen Redux-Reduzierern verwende.

Mike K.
quelle
0

Eine der möglichen Lösungen ist:

const names = {
afshin: 'afshin',
saeed: 'saeed',
larry: 'larry'
};

switch (varName) {
   case names[varName]: {
       alert('Hey');
       break;
   }

   default: {
       alert('Default case');
       break;
   }
}
Jackkobec
quelle
Q pls welches #ecma ist das?
BG Bruno
Hallo. Dies ist ES6
Jackkobec
0

Für mich ist das der einfachste Weg:

switch (["afshin","saeed","larry"].includes(varName) ? 1 : 2) {
   case 1: 
       alert('Hey');
       break;

   default: 
       alert('Default case');
       break;
}
José Pérez Bautista
quelle
-1

Eine andere Möglichkeit, mehrere Fälle in der switch-Anweisung innerhalb einer Funktion auszuführen

function name(varName){
  switch (varName) {
     case 'afshin':
     case 'saeed':
     case 'larry':
       return 'Hey';
     default:
       return 'Default case';
   }
}
        
console.log(name('afshin')); //Hey

Morris S.
quelle
-2

Sie könnten es so schreiben:

switch (varName)
{
   case "afshin": 
   case "saeed": 
   case "larry": 
       alert('Hey');
       break;

   default: 
       alert('Default case');
       break;
}         
Tim Anishere
quelle
6
Dies ist die gleiche Antwort wie alle anderen, ich werde das ", das Sie vergessen haben, beheben, aber denken Sie darüber nach, dies zu löschen.
Gaunt
-3
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Example1</title>
    <link rel="stylesheet" href="css/style.css" >
    <script src="js/jquery-1.11.3.min.js" type="text/javascript"></script>
    <script>
        function display_case(){
            var num =   document.getElementById('number').value;

                switch(num){

                    case (num = "1"):
                    document.getElementById("result").innerHTML = "You select day Sunday";
                    break;

                    case (num = "2"):
                    document.getElementById("result").innerHTML = "You select day  Monday";
                    break;

                    case (num = "3"):
                    document.getElementById("result").innerHTML = "You select day  Tuesday";
                    break;

                    case (num = "4"):
                    document.getElementById("result").innerHTML = "You select day  Wednesday";
                    break;

                    case (num = "5"):
                    document.getElementById("result").innerHTML = "You select day  Thusday";
                    break;

                    case (num = "6"):
                    document.getElementById("result").innerHTML = "You select day  Friday";
                    break;

                    case (num = "7"):
                    document.getElementById("result").innerHTML = "You select day  Saturday";
                    break;

                    default:
                    document.getElementById("result").innerHTML = "You select day  Invalid Weekday";
                    break
                }

        }
    </script>
</head>
<body>
    <center>
        <div id="error"></div>
        <center>
            <h2> Switch Case Example </h2>
            <p>Enter a Number Between 1 to 7</p>
            <input type="text" id="number" />
            <button onclick="display_case();">Check</button><br />
            <div id="result"><b></b></div>
        </center>
    </center>
</body>
Kirandeep Singh
quelle
3
klassische jquery Aufnahme :)
ptim
4
So soll die switchAussage nicht funktionieren. Es ist nur case "1":nicht case (num = "1"):.
user4642212
Warum setzen Sie den Tageswert nicht innerhalb und document.getElementById("result").innerHTML = ....außerhalb des Schalters und addieren das Tageswertergebnis am Ende?
Steffo Dimfelt
@Xufox Ich liebe es, wie er buchstäblich überschreibt, numaber es funktioniert immer noch, weil das switchbereits ausgewertet wurde und die Zuweisung den Wert ergibt. Dies ist Programmierung durch Mutation / maschinelles Lernen vom Feinsten.
Mihail Malostanidis
-3

Schalten Sie einfach den Schalterzustand vor

switch (true) {
    case (function(){ return true; })():
        alert('true');
        break;
    case (function(){ return false; })():
        alert('false');
        break;
    default:
        alert('default');
}
Stefano Favero
quelle
2
Wenn Sie true als Schalterausdruck eingeben, können Sie in den "case" -Anweisungen bewerten, was Sie wollen, vorausgesetzt, Sie geben einen Booleschen Wert zurück
Stefano Favero
1
Ich denke, was er damit gemeint hat, ist, dass Sie einen Ausdruck in die Funktion
einfügen
Für diesen @ StefanoFavero-Hinweis benötigen Sie eigentlich keine Funktion, nur (expression)in Klammern, und der Rückgabewert muss die Eingabe sein. Siehe meine Antwort
Z. Khullah
Warum hast du es missbraucht? Ich befürworte diese Lösung, weil sie Flexibilität für komplexe Bedingungen bietet. Auch wenn Sie Funk als Bedingungen nicht mögen, können Sie sie durch mehrere Bedingungen wieswitch(true) { case (var1 === 0 && var2 === true): {} }
AlexNikonov