javascript:switchケースで条件を使用する


88

そのばかげた質問でごめんなさい。javascriptのswitch-case言語要素でcaseの条件を使用するにはどうすればよいですか?以下の例のように、変数liCountが<= 5かつ> 0の場合はケースが一致する必要があります。ただし、私のコードは機能しません。

switch (liCount) {
    case 0:
        setLayoutState('start');
        var api = $('#UploadList').data('jsp');
        api.reinitialise();
        break;
    case (liCount<=5 && liCount>0):
        setLayoutState('upload1Row');
        var api = $('#UploadList').data('jsp');
        api.reinitialise();
        break;
    case (liCount<=10 && liCount>5):
        setLayoutState('upload2Rows');
        var api = $('#UploadList').data('jsp');
        api.reinitialise();
        break;
    case (liCount>10):
        var api = $('#UploadList').data('jsp');
        api.reinitialise();
        break;                  
}

アドバイスありがとうございます!


4
代わりにifステートメントを使用します
。– Naftali別名Neal 2011

3
if彼らは正しいので、あなたはあなたにsを使うように言っているすべての人を無視するべきではありません。これはのひどいアプリケーションですswitch
lincolnk 2014

このソリューションが提供されていないなんて信じられません。これを行うことができます。ステートメントは、switch句の値に評価する必要があります。これは動作しますので、:var liCount = 2; switch (liCount) { case 0: console.log(0); break; case (liCount<=5 && liCount>0) && liCount: console.log('liCount<=5 && liCount>0'); break; case (liCount<=10 && liCount>5) && liCount: console.log('liCount<=10 && liCount>5'); break; case (liCount>10) && liCount: console.log(liCount); break; }
Noitidart

回答:


285

これは機能します:

switch (true) {
    case liCount == 0:
        setLayoutState('start');
        var api = $('#UploadList').data('jsp');
        api.reinitialise();
        break;
    case liCount<=5 && liCount>0:
        setLayoutState('upload1Row');
        var api = $('#UploadList').data('jsp');
        api.reinitialise();
        break;
    case liCount<=10 && liCount>5:
        setLayoutState('upload2Rows');
        var api = $('#UploadList').data('jsp');
        api.reinitialise();
        break;
    case liCount>10:
        var api = $('#UploadList').data('jsp');
        api.reinitialise();
        break;                  
}

この回答の以前のバージョンでは、括弧が原因であると見なされていました。実のところ、ここでは括弧は関係ありません。必要なのはswitch(true){...}、ケース式がブール値に評価されることだけです。

これは、スイッチに指定した値が比較の基準として使用されるために機能します。したがって、ブール値を評価するケース式によって、実行されるケースが決まります。また、これを好転させswitch(false){..}て、目的の式を真ではなく偽に評価させることもできますが、個人的には、真実と評価される条件を処理することを好みます。ただし、それも機能するので、それが何をしているのかを理解することを覚えておく価値があります。

例:liCountが3の場合、最初の比較はtrue === (liCount == 0)であり、最初のケースがfalseであることを意味します。その後、スイッチは次のケースに進みtrue === (liCount<=5 && liCount>0)ます。この式はtrueと評価されます。つまり、このケースが実行され、で終了しますbreak。わかりやすくするためにここに括弧を追加しましたが、式の複雑さに応じてオプションです。

それは非常に単純で、長い一連の条件を処理するためのきちんとした方法(それがあなたがやろうとしていることに合う場合)であり、おそらく長い一連の条件ìf() ... else if() ... else if () ...は多くの視覚的なノイズや脆弱性をもたらす可能性があります。

有効なコードであるにもかかわらず、非標準のパターンであるため、注意して使用してください。


9
私はあなたが持っている必要があると思いますswitch(true) {、そしてcase liCount == 0:そうですか?それ以外の場合、この比較はliCount == (liCount <=5 && liCount > 0)です。
loganfsmyth 2012年

33
あなたが知っている、それはあなたがすべきであることができるからではありませ。これは火で殺す必要があるものです。
JBert 2014

21
それは言語の一部です-したがって、それについて知ることはそうでないよりはましです。明らかに、すべての状況に適しているわけではありませんが、純粋に主観的なレベルでは、これは興味深いアプローチであり、この場合の一連のif / elifよりも読みやすく/壊れにくいと思います。覚えておくべき重要なことは、コーディングは意図の表現であり、味と実践と結びついているということです。コードで自分自身を明確に表現するためのより多くのオプションがあることは決して悪いことではありません。
dmp 2014年

1
私にとって、これは非常に便利で、if条件に基づいて変数名を何度も使用する必要があるロジックを整理するための非常に優れた方法でしたが、n + 1タイプのシナリオであったため、switchステートメントが休憩は下の次の行に移動します非常に役に立ちました。
ジョセフアストラハン2017年

2
あなたは私たちの目を開いて、スイッチ式がそのように偽である場合の結果がどうなるかを見ました switch(false) { }
bellohargbola19年

24

あなたはましな方法は、それをovercomplicated。代わりに次のようにifステートメントを使用して記述します。

if(liCount == 0)
    setLayoutState('start');
else if(liCount<=5)
    setLayoutState('upload1Row');
else if(liCount<=10)
    setLayoutState('upload2Rows');

$('#UploadList').data('jsp').reinitialise();

または、ChaosPandionが可能な限り最適化しようとしている場合:

setLayoutState(liCount == 0 ? 'start' :
               liCount <= 5 ? 'upload1Row' :
               liCount <= 10 ? 'upload2Rows' :
               null);

$('#UploadList').data('jsp').reinitialise();

あなたは行って、私を1つ上げなければなりませんでした。:)
ChaosPandion 2011年

同時に投稿しました。私はすでに投稿するまであなたを見ませんでした。あなたは...今それをやり過ぎているように見える
エリック・

うわー、私はあまりにも複雑な条件については本当に考えていませんでした。
ChaosPandion 2011年

1
@カオス:ええ、それはおそらくそれをやり過ぎています。setLayoutState:Pにもnullチェックを追加する必要があります。
エリック

@ Eric-私が言っているよりも多くのプログラミングラップを抱えているプログラマーもいます:「中かっこなしで(そして実際には注意して-セミコロンで)Javascriptを書くことができるからといって、そうすべきだという意味ではありません」、しかし私はいくつかの複数を書き直しましたとにかくあなたの例のようなifステートメントなので、ありがとう-条件の後に実行する行が複数あるまでは正常に機能します。三元的な解決策は私には遠すぎる橋でしたが…
Dave Everitt 2016年

7

ifステートメントを使用します。

if (liCount === 0) {
    setLayoutState('start');
} else if (liCount <= 5) {
    setLayoutState('upload1Row');
} else if (liCount <= 10) {
    setLayoutState('upload2Rows');
}
$('#UploadList').data('jsp').reinitialise();  

7

dmpの答えを見る以下の。できればこの回答を削除しますが、受け入れられたので、これが次善の策です:)

できません。JSインタープリターでは、switchステートメントと比較する必要があります(たとえば、「casewhen」ステートメントはありません)。あなたが本当にこれをしたいのなら、あなたはただif(){ .. } else if(){ .. }ブロックを作ることができます。


9
それは正しくありません。これが機能していることを示すデモです:jsfiddle.net/Ender/fr3wL。ECMAScript標準では、これが許可されることが明示的に示さ
Ender

3
@Enderそれはhaemseがやろうとしていることとどのように同じですか?
aistina 2012年

@Aistinaそうではありません。彼のケース条件は数値ではなく真/偽の値を生成するため、haemseは、の数値に対してテストするのではなく、真の値(danpの回答で示唆されているなど)についてケースをテストする必要がありliCountます。「JSインタープリターはcaseステートメントが静的な値である必要がある」というcwolvesの元のステートメントが正しくないことを単に指摘していました。cwolvesはその後この声明を改訂したので、私のコメントはもはや関係ありません。
エンダー2012年

これは質問に答えないからです。彼はそれを行うための別の方法を求めていませんでした、彼はスイッチケースを彼が望むように機能させるように求めました。「他の方法でやる」というのは、私たちがいつもそう思っているにもかかわらず、ほとんど正解ではありません。私たちは常により良い方法があると考えていますが、それは彼がそれを望んでいる方法ではなく、この答えをまったく間違っています。
ジャスミン

@ Jasmine-「できないので、他の方法で行う」が正しければ、完全に有効です。私の答えは間違っているので反対票を投じています:)@ danpが指摘したように、あなたはただ切り替えることができtrue、それは機能します。でも3歳以上なのであまり気にしません。
マークカーン

5
switch (true) {
  case condition0:
    ...
    break;
  case condition1:
    ...
    break;
}

条件が適切なboolean値を返す限りJavaScriptで機能しますが、else ifステートメントに比べて多くの利点はありません。


10switchステートメントで整数sayを渡すと機能しますか?私の場合、うまくいかない理由は何ですか。
PardeepJain19年

10 !== true、いいえ。値を持つ可能性のある変数はあります10か?の場合x、それからcase x === 10:動作します。
マイクサミュエル

しかし、他のステートメントと同じように機能するはずです。たとえば、if (10) {..}フローを使用する場合は、If条件を渡す必要がありますね。10または0以外の整数は真の値として扱われ、条件に入ることができるためです。ここで彼のswitchステートメントの何が問題になっているのかわかりません。
PardeepJain19年

1
@PardeepJainは、switch単にのようには機能しませんifif条件が真であるかどうかをテストします。 is (CaseClauseIsSelectedステップ4)の後の式が。の後の式の値であるswitchかどうかをテストします。switch===case
マイクサミュエル

ああ、そうだね、ありがとう。これは私にとって全く新しいことでした。@Mike
PardeepJain19年


4

それがあなたがしたいことであるならば、ifステートメントを使うほうがよいでしょう。例えば:

if(liCount == 0){
    setLayoutState('start');
}
if(liCount<=5 && liCount>0){
    setLayoutState('upload1Row');
}
if(liCount<=10 && liCount>5){
    setLayoutState('upload2Rows');
}             
var api = $('#UploadList').data('jsp');
    api.reinitialise();

2

あなたのコードはあなたが期待していることをしていないので機能しません。スイッチブロックは値を受け取り、それぞれのケースを指定された値と比較して、等しいかどうかを探します。比較値は整数ですが、ほとんどのケース式はブール値に解決されます。

したがって、たとえば、と言いliCount = 2ます。ので、最初のケースは一致しません2 != 0。2番目のケースは、と(liCount<=5 && liCount>0)評価されますtrue2 != true、なので、このケースも一致しません。

このため、他の多くの人が言っているように、if...then...else ifこれを行うには一連のブロックを使用する必要があります。


2

可能な値が整数の場合は、ケースをまとめることができます。それ以外の場合は、ifsを使用します。

var api, tem;

switch(liCount){
    case 0:
    tem= 'start';
    break;
    case 1: case 2: case 3: case 4: case 5:
    tem= 'upload1Row';
    break;
    case 6: case 7: case 8: case 9: case 10:
    tem= 'upload2Rows';
    break;
    default:
    break;
}
if(tem) setLayoutState((tem);
api= $('#UploadList').data('jsp');
api.reinitialise();

0

スイッチにスコアを渡さないが、trueであることに注意してください。スイッチに与える値は、比較の基準として使用されます。

次の例は、ifステートメントなしでcaseに条件を追加する方法を示しています。

function getGrade(score) {
    let grade;
    // Write your code here
    switch(true) {
        case score >= 0 && score <= 5:
        grade = 'F';
        break;
        case score > 5 && score <= 10:
        grade = 'E';
        break;
        case score > 10 && score <= 15:
        grade = 'D';
        break;
        case score > 15 && score <= 20:
        grade = 'C';
        break;
        case score > 20 && score <= 25:
        grade = 'B';
        break;
        case score > 25 && score <= 30:
        grade = 'A';
        break;
    }

    return grade;
}

0

OPの質問の特定の例ではswitch適切ではありませんが、切り替えが適切/有益である例がありますが、他の評価式も必要です。これは、式のデフォルト句を使用することで実現できます。

switch (foo) {
  case 'bar':
    // do something
    break;
  case 'foo':
    // do something
    break;
  ... // other plain comparison cases
  default:
    if (foo.length > 16) {
      // something specific
    } else if (foo.length < 2) {
      // maybe error
    } else {
      // default action for everything else
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.