web-dev-qa-db-ja.com

JavaScriptを使用してswitch caseステートメントで範囲を使用するにはどうすればよいですか?

JavaScriptを使用してswitch caseステートメントで範囲を使用するにはどうすればよいですか?そのため、可能性のあるものごとにコードを書く代わりに、それらを範囲でグループ化したいと思います。例えば:

switch(myInterval){
   case 0-2:
      //doStuffWithFirstRange();
      break;

   case 3-6:
      //doStuffWithSecondRange();
      break;

   case 6-7:
      //doStuffWithThirdRange();
      break;

   default:
      //doStuffWithAllOthers();
}
29
Lave Loos

少なくとも4つのオプションがあります。

1.各caseをリ​​ストします

LightStyleで示されているように 、各ケースを明示的にリストできます。

switch(myInterval){

    case 0:
    case 1:
    case 2:
        doStuffWithFirstRange();
        break;

    case 3:
    case 4:
    case 5:
        doStuffWithSecondRange();
        break;

    case 6:
    case 7:
        doStuffWithThirdRange();
        break;

    default:
        doStuffWithAllOthers();
}

2. if/else if/elseを使用します

範囲が大きい場合は扱いにくいため、範囲を指定する必要があります。 if...else if...else ifを使用すると、前のものが一致する場合、後のものに到達しないため、毎回上限のみを指定する必要があることに注意してください。わかりやすくするために/*...*/に下限を含めますが、通常はメンテナンスの問題を避けるために省略します(両方の境界を含めると、一方を変更し、もう一方を変更するのを忘れやすくなります)。

if (myInterval < 0) {
    // I'm guessing this is an error
}
else if (/* myInterval >= 0 && */ myInterval <= 2){
    doStuffWithFirstRange();
}
else if (/* myInterval >= 3 && */ myInterval <= 5) {
    doStuffWithSecondRange();
}
else if (/* myInterval >= 6 && */ myInterval <= 7) {
    doStuffWithThirdRange();
}
else {
    doStuffWithAllOthers();
}

3.式でcaseを使用します。

JavaScriptは、caseステートメントで式を使用できるという点で珍しいため、上記のif...else if...else ifシーケンスをswitchステートメントとして記述できます。

switch (true){

    case myInterval < 0:
        // I'm guessing this is an error
        break;    
    case /* myInterval >= 0 && */ myInterval <= 2:
        doStuffWithFirstRange();
        break;

    case /* myInterval >= 3 && */ myInterval <= 5:
        doStuffWithSecondRange();
        break;

    case /* myInterval >= 6 && */ myInterval <= 7:
        doStuffWithThirdRange();
        break;

    default:
        doStuffWithAllOthers();
}

私はそれを支持していませんが、それは / JavaScriptのオプションであり、役に立つ場合があります。 caseステートメントは、in orderswitchで指定した値と照合されます。 (繰り返しますが、多くの場合、下限は以前に一致していたため省略できました。)casesはソースコードの順序で処理されますが、defaultは最後に))、一致するcasesがないか、caseが一致し、デフォルトに達した場合にのみ処理されます(breakがなかった;それを行うことはめったにありませんが、起こります)。

4.ディスパッチマップを使用する

すべての関数が同じ引数をとる場合(そして、引数がまったくない場合も、同じ引数になる場合もあります)、別のアプローチはディスパッチマップです。

いくつかのセットアップコードで:

var dispatcher = {
    0: doStuffWithFirstRange,
    1: doStuffWithFirstRange,
    2: doStuffWithFirstRange,

    3: doStuffWithSecondRange,
    4: doStuffWithSecondRange,
    5: doStuffWithSecondRange,

    6: doStuffWithThirdRange,
    7: doStuffWithThirdRange
};

次に、スイッチの代わりに:

(dispatcher[myInterval] || doStuffWithAllOthers)();

これは、dispatcherマップで呼び出す関数を検索し、 奇妙に強力な||演算子 を使用してその特定のdoStuffWithAllOthers値のエントリがない場合にデフォルトでmyIntervalになり、それを呼び出します。

これを2行に分割して、少しわかりやすくします。

var f = dispatcher[myInterval] || doStuffWithAllOthers;
f();

最大の柔軟性を得るためにオブジェクトを使用しました。あなたの特定の例で、このようにdispatcherを定義する could

var dispatcher = [
    /* 0-2 */
    doStuffWithFirstRange,
    doStuffWithFirstRange,
    doStuffWithFirstRange,

    /* 3-5 */
    doStuffWithSecondRange,
    doStuffWithSecondRange,
    doStuffWithSecondRange,

    /* 6-7 */
    doStuffWithThirdRange,
    doStuffWithThirdRange
];

...ただし、値が連続した数値でない場合は、代わりにオブジェクトを使用する方がはるかに明確です。

76
T.J. Crowder

これはおそらくあなたが必要なものですか?

switch(myInterval){

    case 0:
    case 1:
    case 2:
        //doStuff();
        break;

    case 3:
    case 4:
    case 5:
    case 6:
        //doStuff();
        break;

    case 6:
    case 7:
        //doStuff();
        break;

    default:
        //doStuff();
}

範囲が非常に高くなることがわかっている場合(たとえば、0-100)これを行うこともできます。これは確かに簡単で、クリーンでシンプルです。

if (myInterval >= 0 && myInterval <= 20) {
    //doStuff();
} else if (myInterval > 20 && myInterval <= 60) {
    //doStuff();
} else if (myInterval > 60 && myInterval <= 70) {
    //doStuff();
} else /* it is greater than 70 */ {
    //doStuff();
}
6

この例の範囲は非常に小さいですが、 JavaScript MDN Docs ごとに、より大きな範囲を処理する方法は次のとおりです。

// The value we'll be evaluating:
let code = 100;

// Matches for any case where the expression === `true`:
switch (true) {
  case code <= 64:
    return "Your number is 64 or less!";
    break;
  case code >= 65 && code <= 90:
    return "Your number is in the range of 65-90!";
    break;
  case code >= 97 && code <= 122:
    return "Your number is in the range of 97-122!";
    break;
  case code >= 123:
    return "Your number is 123 or greater!";
    break;
  default:
    break;
}

このスタイルは TJ Crowder via式でcaseを使用、しかし、私はちょうどこの同じ方法を利用する方法の別の例を見せたかったです。私はこれをやったばかりで、他の返信を読んだ後でもまだ少し混乱していたので、別の例が誰かを助けるかもしれないと思っていました。

5
twknab

範囲が同じで0から始まる場合は、いくつかの計算を行うことができます。

doStuffWithRange(Math.floor(myInterval/range));

たとえば、例のようにマップに赤、緑、および青が必要な場合:

  • 範囲0-2はREDにマップします
  • 範囲3〜6は緑にマップされます
  • 範囲7〜8は青にマップされます

あなたは書ける:

function colorInterval(n, max) {
     var colors = ["RED", "GREEN", "BLUE"];
     var range = max/colors.length
     return colors[Math.floor(n/range)];
 }

//You get 3 of RED, 3 of GREEN, 2 of BLUE
for (var i=0; i<8; i++) {
    console.log(colorInterval(i, 8));
} 

例の最後の範囲は3ではなく2であり、前の範囲が同じである限り、これは引き続き機能することに注意してください。

2
iamdimitar

特に間隔が0で始まるように、すでに投稿されている優れた回答に少しの多様性を追加するために、findIndexYeah ES6 )を使用したソリューションを次に示します。

const range = [0, 2, 6, 7];
const randeIndex = range.findIndex(threshold => myInterval <= threshold);
switch (rangeIndex) {
  case 1:
    //doStuffWithFirstRange();
    break;

  case 2:
    //doStuffWithSecondRange();
    break;

  case 3:
    //doStuffWithThirdRange();
    break;
  default:
  //doStuffWithAllOthers();
}

range配列が順序付けられているため、findIndexは最初の配列と一致します。範囲に応じてname、0または1から始まり、rangeの最初の0を削除する必要があります。

0
Al-un

int levelNumber = YOUR_VALUE FROM

NSString* strMessage;

switch (levelNumber) {
    case 1...10:
    {
        // Do something...
        break;
    }
    case 11...20:
    {
        // Do something...
        break;
    }
    case 21...30:
    {
        // Do something...
        break;
    }
    case 31...40:
    {
        // Do something...
        break;
    }
    default:
        break;
}

参照:https://www.codingexplorer.com/loops-switch-statements-ranges-Swift/

0