JavaScriptでのswitchステートメントの複数のケース


768

JavaScriptのswitchステートメントで複数のケースが必要です、次のようなもの:

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

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

どうやってやるの?JavaScriptでそのようなことを行う方法がない場合は、DRYの概念にも従う代替ソリューションを知りたいです。


5
この質問を閉じるために投票した人に。それは5年以上前のものであり、適切な回答があります-なぜ最終投票ですか?
surfmuggle

回答を追加する必要がないため、@ surfmuggle。
Afshin Mehrabani

7
@AfshinMehrabani多分それは閉鎖するのではなく、保護することができますか?
evolutionxbox

回答:


1510

switchステートメントのフォールスルー機能を使用します。一致したケースはbreak(またはswitchステートメントの終わり)が見つかるまで実行されるため、次のように記述できます。

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

   default: 
       alert('Default case');
}


2
どういうわけか、それは、JavaScriptコンソールで、Chromeで私の作品:switch('10') { case 1, '10': console.log('ok') }版画ok
nafg

8
@nafg:試してくださいswitch(1)。ここのラベルは単なるコンマ式です。
kennytm

4
@Barneyいいえ、休憩がなければ次のケースに陥ります。
セイリア2015

1
@Seiyiraの定義により、最後の後に次のケースはありません。その上、それはデフォルトです。
Barney

101

これは通常の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);

乾杯。


13
@believesInSantaそれは文字通り通常のケースであり、奇妙なフォーマット(改行ではなくスペース)のフォールスルーです
Mihail Malostanidis

42

switchステートメントを完全に回避する別の方法を次に示します。

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

cases[ varName ] ? cases[ varName ]() : cases._default();

5
私は間違いなくこのバージョンを好みます。フォールスルーは、のバグが発生しやすい機能ですswitch ... casebreakステートメントを忘れるのは簡単すぎるため、フォールスルーを意図的に使用すると、それらの忘れられたbreakステートメントを見つけるのが非常に難しくなる可能性があります。このメソッド検索バージョンにswitch ... caseは、動的な拡張性や、オブジェクトを完全に置き換えてモード切り替えを実行する機能など、欠けている多くの優れた機能もあります。また、整理された状態を維持するのが簡単になり、コードをより保守しやすくなります。ericleads.com/2012/12/switch-case-considered-harmfulを
エリックエリオット

31
意図的にを省略した場合は//fallthrough、の代わりにbreak常にコメントを追加しbreakます。これは、それが間違いであるか、それが意図的であるかを識別するのに役立ちます。
Mnebuerquo 14

18
直感的なアプローチ。ただし、読みやすくするために、ネイティブのswitchステートメントを使用することをお勧めします。
contactmatt 2014年

39
右耳を首の後ろに通して、左耳をいつでも引っ掻くことができます...この複雑な解決策を支持することは、正しいことではないようです...)
クリントイーストウッド

25
これが34票を獲得したことに本当に驚いています。可読性と保守性の点で、これは絶対に恐ろしいことです。どの条件が何かをトリガーするかを確認したい場合、caseステートメントは非常にシンプルで、ラベルを見れば簡単に確認できます。一方、あなたのバージョンでは、誰かがほとんどすべての行を読んで、どこに割り当てたかを確認する必要があります。これはまた、一致させたいケースが多いほどさらに悪化します。
マイケル2016年

21

スイッチで複数のケースを割り当てるJavaScriptでは、different case without break inbetween以下のように定義する必要があります。

   <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>

リンクをクリックして例をご覧ください


5
これはJSに縛られない、多くの言語で一般的な手法です
drAlberT

13

ES6を使用している場合、これを行うことができます。

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

または、以前のバージョンのJavaScriptの場合、これを行うことができます。

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

これは古いIEブラウザーでは機能しませんが、かなり簡単に修正できます。詳細については、JavaScriptのリストに文字列が含まれているかどうかを確認する質問を参照してください。


スイッチよりも優れている点は何ですか?
ブライススナイダー

@BryceSnyder式とステートメントの違いは?タイピングが少ない?消費される垂直線が少なくなりますか?簡潔さと表現の密度による表現力の向上?includes言葉を通してより良い意味論?好きなものを選んでください。
ErikE

7

ノードでは、これを行うことが許可されているようです:

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;
}

これにより、場合によってはコードがはるかにコンパクトになります。


1
構文は他のJS環境と同じだと思います。
Afshin Mehrabani 2015

1
@AfshinMehrabaniたぶん、私はそれをnodejsコンテキストでテストしただけです。
Automatico

はい。縦のスペースを節約したい!
チャネル

7

ステファノの答えを追加して明確にすると、式を使用してスイッチの条件の値を動的に設定できます。例:

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

だからあなたの問題では、あなたは次のようなことをすることができます:

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

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

あまりドライではありませんが…


まだテストされていませんがvarName、ケース式の内部を変更することは興味深いでしょう。varNameがキャッシュされていることを期待してください。
Valen

5

' in '演算子を使用でき
ます...オブジェクト/ハッシュの呼び出しに依存しています...
そのため、JavaScriptと同じくらい高速です...

// 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]()

お楽しみください、ZEE


これはスイッチとどのように関係していますか?それを明確にできますか?
Z. Khullah

なぜコードを「読みにくく」したいのですか?私がプログラマーとして最初に言われたことは、あなたのコードを読んでいる次の人は斧を使うシリアルキラーであり、彼はコードを理解できないことを嫌うという考え方でコードを書くことでした。
MattE 2018

こんにちはマット...私はここに概念の証明としてそれを提示しています...とにかく、このフォームはより多くの機能と柔軟性を提供します...そしてあなたが望む場合にのみ、またはあなたの制約を見つけた場合にのみ使用します物事の通常の形...プログラマツールボックスでirをもう1つのツールと考えてください...
ZEE

5

私はこのように使用します:

switch (true){
     case /Pressure/.test(sensor):{
        console.log('Its pressure!');
        break;
     }
     case /Temperature/.test(sensor):{
        console.log('Its temperature!');
        break;
     }
}

g正規表現を一度だけ使用して破棄するので、フラグを使用する必要はありません。実際、関数の外でそれらを保持している場合、gフラグは後続.test(のの0以外のインデックスから照合しようとすることによって害を及ぼします。また、ブール式に一致させるために、スイッチケースがsensor変数ではなくtrue定数であるタイプミスを修正しました。編集を参照してください。
ミハイルマロスタニディス

この形式を使用して、ファイルの種類をテストしました。例:case /officedocument/.test(type) && /presentation/.test(type): iconClass = "far fa-file-powerpoint red"; break;
tbone849

4

場合によります。 スイッチは一度だけ評価されます。一致すると、ケースが何を言っていても、 'break'までの後続のすべてのcaseステートメントが起動します。

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>


3

わかりやすく、DRY構文が好きなので、これが好きです。

varName = "larry";

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

    default: 
       alert('Default case');

}

2

ここには良い答えがたくさんあることがわかりますが、10を超えるケースをチェックする必要がある場合はどうなりますか?ここに私自身のアプローチがあります:

 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'));

1
これは、switchステートメントの乱用です。ただif (accessDenied.includes(varName)) return 'Access Denied!'; return 'Access Allowed.'十分です。
ミハイルマロスタニディス

2

上記のアプローチの問題はcase、を含む関数を呼び出すたびに数秒を繰り返す必要があることですswitch。より堅牢なソリューションは、マップまたは辞書を用意することです。

ここに例

// 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')
}


1

あなたはこれを行うことができます:

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

または1行のコード:

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

ErikEの回答から少し改善


1

何週間ものコーディングとバーンアウトの後に遭遇した、私が経験したのと同じような問題を抱えてここに来た人にとって、私の状況は次のようなものでした:

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');
}

常にdefaultケースに入った。同様の複数ケースのswitchステートメントの問題が発生している場合、探しているのは次のとおりです。

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');
}

これが誰かのお役に立てば幸いです。私は、reduxレデューサーでスイッチケースを使用するのと同じ方法でスイッチケースを使用することを思い出す前に、髪の毛を引っ張っていました。


0

可能な解決策の1つは次のとおりです。

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

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

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

これは#ecmaですか?
BG Bruno

こんにちは。これはES6です
Jackkobec


-1

関数内で、switchステートメントで複数のケースを実行する別の方法

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


-2

次のように書くことができます:

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

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

6
これは誰もが、私はあなたが忘れてしまった」と修正し、これを削除することを考えますと同じ答えである。
やつれ

-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>

3
クラシックjqueryの包含:)
ptim

4
これは、switchステートメントが機能するはずの方法ではありません。それだけcase "1":ではありませんcase (num = "1"):
user4642212 2017

ケースの内側とdocument.getElementById("result").innerHTML = ....スイッチの外側に日の値を入れて、最後に日の値の結果を追加してみませんか?
Steffo Dimfelt

@Xufox私は彼が文字通り上書きする方法が大好きですnumが、それswitchはすでに評価されており、割り当てが値を生成するため、引き続き機能します。これは、突然変異/機械学習によるプログラミングです。
ミハイルマロスタニディス

-3

単にスイッチ条件を切り替えます

switch (true) {
    case (function(){ return true; })():
        alert('true');
        break;
    case (function(){ return false; })():
        alert('false');
        break;
    default:
        alert('default');
}

2
スイッチ式としてtrueを指定した場合、「case」ステートメントでブール値を返す限り、何でも評価できます
Stefano Favero

1
私は、このように複雑な条件のすべての種類をできるように、ケースのための動的な値を評価して返します誰が、何を彼が意味することは、あなたが関数内で式を置くことができるということだと思う
Z. Khullah

この@StefanoFaveroのメモでは(expression)、括弧内の関数は実際には必要ありません。戻り値は入力でなければなりません。私の答えをご覧ください
Z. Khullah

なぜマイナスしたの?? このソリューションは、複雑な条件に柔軟に対応できるため、推奨しています。あなたが条件とのfuncsを好まない場合でも、あなたのようなあなたの複数の条件に置き換えることswitch(true) { case (var1 === 0 && var2 === true): {} }
AlexNikonov
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.