Beralih pernyataan beberapa kasus dalam JavaScript

768

Saya perlu beberapa kasus dalam pernyataan beralih dalam JavaScript, Sesuatu seperti:

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

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

Bagaimana saya bisa melakukan itu? Jika tidak ada cara untuk melakukan hal seperti itu di JavaScript, saya ingin tahu solusi alternatif yang juga mengikuti konsep KERING .

Afshin Mehrabani
sumber
5
Kepada orang yang memilih untuk menutup pertanyaan ini. Umurnya lebih dari 5 tahun dan memiliki jawaban yang beralasan - mengapa memilih secara dekat?
surfmuggle
@ surfmuggle karena tidak perlu menambahkan lebih banyak jawaban.
Afshin Mehrabani
7
@AfshinMehrabani mungkin bisa dilindungi, bukan ditutup?
evolutionxbox

Jawaban:

1510

Gunakan fitur fall-through dari switchpernyataan tersebut. Kasing yang cocok akan berjalan hingga break(atau akhir switchpernyataan) ditemukan, sehingga Anda dapat menulisnya seperti:

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

   default: 
       alert('Default case');
}
kennytm
sumber
2
Entah bagaimana itu bekerja untuk saya di Chrome, di konsol javascript: switch('10') { case 1, '10': console.log('ok') }cetakanok
nafg
8
@ nafg: Coba switch(1). Label di sini hanyalah ekspresi koma.
kennytm
4
@ Barney Tidak, tanpa istirahat Anda bisa jatuh ke kasus berikutnya.
Seiyria
1
@ Suyira menurut definisi, tidak ada kasus berikutnya setelah yang terakhir. Selain itu, ini adalah default.
Barney
101

Ini berfungsi dalam JavaScript biasa

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

Bersulang.

Rob Welan
sumber
13
@believesInSanta ini benar-benar hanya kasus normal dengan format aneh (spasi bukan baris baru)
Mihail Malostanidis
42

Inilah pendekatan berbeda yang menghindari switchpernyataan itu sama sekali:

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

cases[ varName ] ? cases[ varName ]() : cases._default();
elclanrs
sumber
5
Saya lebih suka versi ini. Jatuh adalah fitur rawan bug switch ... case. Terlalu mudah untuk melupakan breakpernyataan, dan jika Anda menggunakan fall through dengan sengaja, breakpernyataan yang dilupakan itu bisa sangat sulit dikenali. Versi pencarian metode ini juga memiliki banyak fitur hebat yang switch ... casekurang, seperti ekstensibilitas dinamis, atau kemampuan untuk sepenuhnya mengganti objek untuk mencapai mode switching. Ini juga lebih mudah untuk tetap rapi, dan dapat mengarah pada kode yang lebih dapat dipelihara. Lihat ericleads.com/2012/12/switch-case-considered-harmful
Eric Elliott
31
Saya selalu menambahkan komentar //fallthroughdi tempat breaksetiap kali saya sengaja menghilangkan break. Itu membantu mengidentifikasi kapan itu kesalahan dan kapan disengaja.
Mnebuerquo
18
Pendekatan intuitif. Namun, untuk keterbacaan, saya akan merekomendasikan untuk menggunakan pernyataan saklar asli.
contactmatt
39
Seseorang selalu dapat menggaruk telinga kiri melewati tangan kanannya melalui bagian belakang leher ... (maaf untuk bahasa Inggris saya, maksud saya: "seseorang selalu dapat menyulitkan hal-hal sebanyak mungkin ... dalam hal ini, menghindari pergantian pernyataan mendukung solusi rumit ini sepertinya bukan hal yang tepat untuk dilakukan ...)
Clint Eastwood
25
Saya benar-benar kagum bagaimana ini mendapatkan 34 suara. Dalam hal keterbacaan dan pemeliharaan, ini benar-benar mengerikan. Jika saya ingin melihat kondisi apa yang akan memicu sesuatu, pernyataan kasus sangat sederhana dan mudah dilihat dengan melihat labelnya. Di sisi lain, versi Anda mengharuskan seseorang membaca hampir setiap baris dan melihat apa yang Anda tetapkan di mana. Ini juga semakin buruk semakin banyak kasus yang ingin Anda cocokkan.
michael
21

Dalam Javascript untuk menetapkan banyak kasus dalam sebuah saklar, kita harus mendefinisikan different case without break inbetweenseperti yang diberikan di bawah ini:

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

Silakan lihat contoh klik pada tautan

Er. Anurag Jain
sumber
5
Ini adalah teknik umum dalam sejumlah bahasa, tidak terikat dengan JS
drAlberT
13

Jika Anda menggunakan ES6, Anda dapat melakukan ini:

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

Atau untuk versi JavaScript yang lebih lama, Anda dapat melakukan ini:

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

Perhatikan bahwa ini tidak akan berfungsi di browser IE yang lebih lama, tetapi Anda bisa menambal dengan cukup mudah. Lihat pertanyaan, tentukan apakah string ada dalam daftar di javascript untuk informasi lebih lanjut.

ErikE
sumber
Apa manfaat dari switch ini?
Bryce Snyder
@BryceSnyder perbedaan antara ekspresi dan pernyataan? Kurang mengetik? Lebih sedikit garis vertikal yang dikonsumsi? Kekuatan ekspresif yang lebih besar melalui ringkas dan padatnya representasi? Semantik yang lebih baik melalui includeskata? Ambil pilihanmu.
ErikE
7

Di simpul tampaknya Anda diizinkan untuk melakukan ini:

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

Ini membuat kode lebih ringkas dalam beberapa kasus.

Otomatis
sumber
1
Saya pikir sintaksnya sama dengan lingkungan JS lainnya.
Afshin Mehrabani
1
@AfshinMehrabani Mungkin, saya hanya mengujinya dalam konteks nodejs.
Otomatis
Iya. Saya suka menghemat ruang vertikal!
Saluran
7

Menambah dan mengklarifikasi jawaban Stefano, Anda dapat menggunakan ekspresi untuk secara dinamis mengatur nilai untuk kondisi yang diaktifkan, misalnya:

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

Jadi dalam masalah Anda, Anda bisa melakukan sesuatu seperti:

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

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

meskipun tidak terlalu KERING ..

Z. Khullah
sumber
belum diuji tetapi akan menarik untuk memodifikasi varNamedi dalam ekspresi case, berharap varName di-cache kamu.
Valen
5

Anda dapat menggunakan operator ' dalam ' ...
bergantung pada objek / permintaan hash ...
sehingga secepat javascript dapat ...

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

Selamat menikmati, ZEE

ZEE
sumber
bagaimana hubungannya dengan beralih? dapatkah Anda menjelaskannya?
Z. Khullah
mengapa Anda ingin membuat kode Anda "sulit dibaca". Hal pertama yang saya diberitahu sebagai seorang programmer adalah menulis kode dengan pola pikir bahwa orang berikutnya yang membaca kode Anda adalah seorang pembunuh berantai yang menggunakan kapak dan dia benci tidak dapat memahami kode.
MattE
Hai Matt ... Saya menyajikannya di sini sebagai bukti konsep ... pokoknya formulir ini memberi Anda lebih banyak fungsi dan fleksibilitas ... dan Anda hanya menggunakannya jika Anda mau ... atau jika Anda menemukan kendala dalam bentuk biasa melakukan hal-hal ... anggap ir sebagai satu alat lagi di kotak alat pemrogram Anda ...
ZEE
5

Saya menggunakan seperti ini:

switch (true){
     case /Pressure/.test(sensor):{
        console.log('Its pressure!');
        break;
     }
     case /Temperature/.test(sensor):{
        console.log('Its temperature!');
        break;
     }
}
Sergey Volkov
sumber
Anda tidak perlu menggunakan gbendera, karena Anda hanya menggunakan regex sekali dan membuangnya. Bahkan, jika Anda menjaga mereka di luar fungsi, gbendera akan membahayakan Anda dengan mencoba mencocokkan dari indeks non-0 pada .test(s berikutnya . Saya juga memperbaiki kesalahan ketik di mana sakelar pada sensorvariabel dan tidak truekonstan untuk mencocokkan ekspresi boolean. Lihat hasil edit.
Mihail Malostanidis
Saya menggunakan format ini untuk menguji jenis file. Contoh:case /officedocument/.test(type) && /presentation/.test(type): iconClass = "far fa-file-powerpoint red"; break;
tbone849
4

Tergantung. Switch mengevaluasi sekali dan hanya sekali. Setelah pertandingan, semua pernyataan kasus berikutnya sampai 'meledak' tidak peduli apa yang dikatakan kasus tersebut.

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

Saya suka ini untuk kejelasan dan sintaks KERING.

varName = "larry";

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

    default: 
       alert('Default case');

}
Kyle Dudley
sumber
2

Saya dapat melihat ada banyak jawaban bagus di sini, tetapi apa yang terjadi jika kita perlu memeriksa lebih dari 10 kasus? Ini pendekatan saya sendiri:

 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
sumber
1
Ini adalah penyalahgunaan pernyataan switch. Hanya if (accessDenied.includes(varName)) return 'Access Denied!'; return 'Access Allowed.'lebih dari cukup.
Mihail Malostanidis
2

Masalah dengan pendekatan di atas, adalah bahwa Anda harus mengulangi beberapa cases setiap kali Anda memanggil fungsi yang memiliki switch. Solusi yang lebih kuat adalah memiliki peta atau kamus .

Berikut sebuah contoh

// 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
sumber
1

Kamu bisa melakukan ini:

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

atau hanya satu baris kode:

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

sedikit perbaikan dari jawaban ErikE

Dedy Abdillah
sumber
1

Bagi siapa pun yang datang ke sini dengan masalah yang sama dengan yang saya alami, yang saya alami setelah beberapa minggu pengkodean dan kejenuhan, situasi saya adalah sesuatu yang mirip dengan:

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

Selalu default dimasukkan. Jika Anda mengalami masalah pernyataan beralih multi-kasus yang serupa, yang Anda cari adalah:

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

Semoga ini bisa membantu seseorang, saya mencabut rambut saya sebelum mengingat untuk menggunakan sakelar dengan cara yang sama seperti saya menggunakannya dalam reduksi redux saya.

Mike K.
sumber
0

Salah satu solusi yang mungkin adalah:

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

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

   default: {
       alert('Default case');
       break;
   }
}
Jackkobec
sumber
Q, yang #ecma ini?
BG Bruno
Hai yang disana. Ini ES6
Jackkobec
0

Bagi saya ini adalah cara paling sederhana:

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

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

Cara lain melakukan banyak kasus dalam pernyataan switch, ketika berada di dalam suatu fungsi

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

Morris S
sumber
-2

Anda bisa menulis seperti ini:

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

   default: 
       alert('Default case');
       break;
}         
Tim Anishere
sumber
6
Ini adalah jawaban yang sama dengan orang lain, saya akan memperbaiki "yang Anda lupa, tetapi pikirkan tentang menghapus ini.
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
sumber
3
inklusi jquery klasik :)
ptim
4
Ini bukan bagaimana switchpernyataan seharusnya bekerja. Hanya saja case "1":, tidak case (num = "1"):.
user4642212
Mengapa tidak memasukkan nilai hari di dalam kasing dan di document.getElementById("result").innerHTML = ....luar sakelar dan menambahkan hasil nilai hari di akhir?
Steffo Dimfelt
@ Xufox Saya suka bagaimana dia benar-benar menimpa numtetapi masih berfungsi karena switchsudah dievaluasi dan tugas menghasilkan nilai. Ini pemrograman dengan mutasi / pembelajaran mesin yang terbaik.
Mihail Malostanidis
-3

cukup alihkan sakelar kondisi sakelar

switch (true) {
    case (function(){ return true; })():
        alert('true');
        break;
    case (function(){ return false; })():
        alert('false');
        break;
    default:
        alert('default');
}
Stefano Favero
sumber
2
Jika Anda menyatakan true sebagai ekspresi switch, dalam pernyataan "case" Anda dapat mengevaluasi apa pun yang Anda inginkan asalkan Anda mengembalikan boolean
Stefano Favero
1
Saya pikir maksudnya adalah Anda dapat menempatkan ekspresi di dalam fungsi, yang akan mengevaluasi dan mengembalikan nilai dinamis untuk kasus ini, sehingga memungkinkan segala macam kondisi rumit
Z. Khullah
Untuk catatan @StefanoFavero ini Anda tidak benar-benar membutuhkan fungsi, hanya (expression)dalam tanda kurung, dan nilai balik harus menjadi input. Lihat jawaban saya
Z. Khullah
mengapa Anda menggunakannya? Saya menganjurkan solusi ini karena memberikan fleksibilitas untuk kondisi yang kompleks. Bahkan jika Anda tidak suka funcs sebagai kondisi, Anda dapat menggantinya dengan beberapa kondisi sepertiswitch(true) { case (var1 === 0 && var2 === true): {} }
AlexNikonov