javascript: menggunakan kondisi dalam kasus sakelar


89

Maaf untuk pertanyaan bodoh itu. Bagaimana saya bisa menggunakan kondisi untuk kasus di elemen bahasa switch-case javascript? Seperti pada contoh di bawah ini, kasus harus cocok jika variabelnya liCount<= 5 dan> 0; namun, kode saya tidak berfungsi:

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

Terima kasih atas sarannya!


4
gunakan pernyataan if sebagai gantinya jika Anda ingin melakukan itu ..
Naftali aka Neal

3
Anda tidak boleh mengabaikan semua orang yang menyuruh Anda menggunakan ifs, karena mereka benar. Ini adalah aplikasi yang buruk dari switch.
lincolnk

Saya tidak percaya solusi ini belum tersedia. Anda dapat melakukan ini, pernyataan hanya perlu mengevaluasi ke nilai dalam klausa sakelar. Jadi ini akan berhasil: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

Jawaban:


291

Ini bekerja:

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

Versi sebelumnya dari jawaban ini menganggap tanda kurung sebagai pelakunya. Sebenarnya, tanda kurung tidak relevan di sini - satu-satunya hal yang diperlukan adalah switch(true){...}dan agar ekspresi kasus Anda dievaluasi menjadi boolean.

Ini berfungsi karena, nilai yang kami berikan ke sakelar digunakan sebagai dasar untuk membandingkan. Akibatnya, ekspresi kasus, juga mengevaluasi ke boolean akan menentukan kasus mana yang dijalankan. Bisa juga membalikkan ini, dan lulus switch(false){..}dan memiliki ekspresi yang diinginkan mengevaluasi salah daripada benar .. tetapi secara pribadi lebih suka berurusan dengan kondisi yang mengevaluasi kebenaran. Namun, itu berhasil juga, jadi perlu diingat untuk memahami apa yang dilakukannya.

Misalnya: jika liCount adalah 3, perbandingan pertama adalah true === (liCount == 0) , artinya kasus pertama salah. Sakelar kemudian beralih ke kasus berikutnya true === (liCount<=5 && liCount>0). Ekspresi ini mengevaluasi true, yang berarti kasus ini dijalankan, dan diakhiri di break. Saya telah menambahkan tanda kurung di sini untuk membuatnya lebih jelas, tetapi itu opsional, tergantung pada kompleksitas ekspresi Anda.

Ini cukup sederhana, dan cara yang rapi (jika sesuai dengan apa yang Anda coba lakukan) untuk menangani serangkaian kondisi yang panjang, di mana mungkin rangkaian panjang ìf() ... else if() ... else if () ... dapat menimbulkan banyak gangguan visual atau kerapuhan.

Gunakan dengan hati-hati, karena ini adalah pola non-standar, meskipun merupakan kode yang valid.


9
Saya pikir Anda harus memilikinya switch(true) {, case liCount == 0:bukan? Jika tidak, perbandingan ini liCount == (liCount <=5 && liCount > 0).
loganfsmyth

33
Kau tahu, itu bukan karena Anda bisa bahwa Anda harus . Ini adalah sesuatu yang perlu dibunuh dengan api.
JBert

21
Itu bagian dari bahasa - akibatnya, mengetahui tentang itu lebih baik daripada tidak. Jelas, ini tidak akan sesuai untuk setiap situasi, tetapi pada tingkat subyektif murni, menurut saya ini adalah pendekatan yang menarik, dan lebih terbaca / kurang rapuh daripada serangkaian ifs / elif dalam kasus ini. Hal penting yang harus diingat adalah bahwa coding adalah ekspresi niat, ditambah dengan rasa dan praktik. Memiliki lebih banyak pilihan untuk mengekspresikan diri Anda dengan jelas dalam kode bukanlah hal yang buruk.
dmp

1
Bagi saya ini sangat berguna dan cara yang sangat bagus untuk mengatur logika saya di mana saya perlu menggunakan nama variabel berulang kali berdasarkan kondisi if, tetapi itu adalah skenario tipe n + 1 jadi fakta bahwa switch statement case tanpa istirahat akan pindah ke baris berikutnya di bawah ini sangat berguna.
Joseph Astrahan

2
Anda bahkan membuka mata kami untuk melihat apa yang akan terjadi jika ekspresi sakelar salah seperti itu switch(false) { }
bello hargbola

24

Anda cara overcomplicated itu. Tuliskan dengan pernyataan if seperti ini:

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

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

Atau, jika ChaosPandion mencoba mengoptimalkan sebanyak mungkin:

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

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

Anda harus pergi dan satu untuk saya. :)
ChaosPandion

Kami menulis posting kami secara bersamaan. Saya tidak melihat milik Anda sampai saya sudah memposting. Anda tampaknya berlebihan sekarang ...
Eric

Wow, saya tidak benar-benar memikirkan persyaratan yang terlalu rumit.
ChaosPandion

1
@Chaos: ya, itu mungkin berlebihan. Anda juga harus menambahkan cek nol ke setLayoutState: P.
Eric

@Eric - beberapa programmer dengan lebih banyak putaran pemrograman daripada yang saya katakan: "hanya karena Anda dapat menulis Javascript tanpa tanda kurung (dan - sebenarnya dengan hati-hati - titik koma) tidak berarti Anda harus", Tapi saya hanya menulis ulang beberapa if pernyataan seperti dalam contoh Anda, jadi terima kasih - berfungsi dengan baik sampai ada lebih dari satu baris untuk dieksekusi setelah kondisi. Solusi terner adalah jembatan yang terlalu jauh bagi saya, meskipun…
Dave Everitt

7

Anda ingin menggunakan pernyataan if:

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

7

Lihat jawaban dmp di bawah ini. Saya akan menghapus jawaban ini jika saya bisa, tetapi jawaban itu diterima jadi ini adalah hal terbaik berikutnya :)

Tidak boleh. Penerjemah JS mengharuskan Anda untuk membandingkan dengan pernyataan switch (misalnya, tidak ada pernyataan "case when"). Jika Anda benar-benar ingin melakukan ini, Anda tinggal membuat if(){ .. } else if(){ .. }balok.


9
Itu salah. Berikut demo yang menunjukkannya bekerja: jsfiddle.net/Ender/fr3wL . Standar ECMAScript secara eksplisit menyatakan bahwa ini diizinkan: docstore.mik.ua/orelly/webprog/jscript/ch06_05.htm#FOOTNOTE-18
Ender

3
@Ender Bagaimana itu sama dengan apa yang Haemse coba lakukan?
Aistina

@Aistina Bukan. Karena kondisi kasusnya menghasilkan nilai benar / salah daripada nilai numerik, haemse perlu menguji kasusnya untuk nilai kebenaran (seperti yang disarankan oleh jawaban danp), daripada menguji nilai numerik dari liCount. Saya hanya menunjukkan bahwa pernyataan asli cwolves bahwa "Penerjemah JS memerlukan pernyataan kasus menjadi nilai statis" tidak benar. cwolves telah merevisi pernyataan ini, jadi komentar saya tidak lagi relevan.
Ender

Karena ini tidak menjawab pertanyaannya. Dia tidak meminta cara lain untuk melakukannya, dia meminta agar sakelar berfungsi seperti yang dia inginkan. "Lakukan dengan cara lain" hampir tidak pernah menjadi jawaban yang benar meskipun kita selalu berpikir demikian. Kami selalu berpikir kami memiliki cara yang lebih baik, tetapi bukan itu yang dia inginkan, membuat jawaban ini salah.
Jasmine

@ Jasmine - "Anda tidak bisa, jadi lakukan dengan cara lain" sangat valid, jika benar . Jawaban saya ditolak karena itu salah :) Seperti yang dikatakan @danp, Anda dapat beralih saja truedan itu berhasil. Tapi usianya sudah lebih dari 3 tahun, jadi saya tidak terlalu peduli.
Mark Kahn

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

akan berfungsi di JavaScript selama kondisi Anda mengembalikan booleannilai yang sesuai , tetapi tidak memiliki banyak keunggulan dibandingkan else ifpernyataan.


Akankah Ini Bekerja Jika saya menyampaikan beberapa bilangan bulat yang dikatakan 10dalam pernyataan switch? dalam kasus saya tidak bekerja tidak yakin apa alasannya.
Pardeep Jain

10 !== true, jadi tidak. Apakah ada variabel yang mungkin memiliki nilai 10? Jika x, maka case x === 10:akan berhasil.
Mike Samuel

Tetapi harus bekerja seperti pernyataan lain misalnya jika Anda menggunakan if (10) {..}aliran harus lulus dalam Ifkondisi, bukan? karena 10 atau bilangan bulat apa pun kecuali 0 akan diperlakukan sebagai nilai kebenaran dan memungkinkan untuk masuk ke dalam kondisi tersebut. Tidak yakin apa yang salah dengan pernyataannya di sini.
Pardeep Jain

1
@PardeepJain, switchsepertinya tidak berfungsi if. iftes apakah kondisi ini truthy . switchtes apakah ekspresi setelah switchini ===( CaseClauseIsSelected langkah 4 ) dengan nilai ekspresi setelah case.
Mike Samuel

Ohh seperti itu, Terima kasih. Ini benar-benar baru bagiku. @Mike
Pardeep Jain


4

Jika itu yang ingin Anda lakukan, akan lebih baik menggunakan ifpernyataan. Sebagai contoh:

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

Kode Anda tidak berfungsi karena tidak melakukan apa yang Anda harapkan. Blok saklar mengambil nilai, dan membandingkan setiap kasus dengan nilai yang diberikan, mencari persamaan. Nilai perbandingan Anda adalah bilangan bulat, tetapi sebagian besar ekspresi kasus Anda menghasilkan nilai boolean.

Jadi, misalnya, katakanlah liCount = 2. Kasus pertama Anda tidak akan cocok, karena 2 != 0. Kasus kedua Anda, (liCount<=5 && liCount>0)mengevaluasi ke true, tapi 2 != true, jadi kasus ini juga tidak akan cocok.

Untuk alasan ini, seperti yang dikatakan banyak orang, Anda harus menggunakan serangkaian if...then...else ifblok untuk melakukan ini.


2

jika nilai yang mungkin adalah bilangan bulat, Anda dapat mengumpulkan kasus. Jika tidak, gunakan 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

Perhatikan bahwa kami tidak memberikan skor ke sakelar tetapi benar. Nilai yang kami berikan ke sakelar digunakan sebagai dasar untuk membandingkan.

Contoh di bawah ini menunjukkan bagaimana kita dapat menambahkan kondisi dalam case: tanpa pernyataan if.

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

Walaupun pada contoh khusus soal OP switchtidak sesuai, ada contoh switch masih sesuai / menguntungkan, namun ekspresi evaluasi lain juga dibutuhkan. Ini dapat dicapai dengan menggunakan klausa default untuk ekspresi:

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

0

Anda dapat menggunakan metode fall-through dalam kasus sakelar.

const x = 'Welcome';

switch (x) {
  case 'Come':
    console.log(1)
    break;

  case 'Welcome':
  case 'Wel':
  case 'come':
    console.log(2)
    break;

  case 'Wel':
    console.log(3)
    break;

  default:
    break;
}

    
> Result => 2
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.