JavaScript'te birden çok durumu ifade etme


767

JavaScript gibi bir şey switch deyiminde birden fazla durumda ihtiyacım var:

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

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

Bunu nasıl yapabilirim? JavaScript'te böyle bir şey yapmanın bir yolu yoksa, DRY konseptini de takip eden alternatif bir çözüm bilmek istiyorum .


5
Bu soruyu kapatmak için oy veren kişiye. 5 yaşından büyük ve haklı bir cevabı var - neden yakın oylama?
25'te surfmuggle

@surfmuggle çünkü daha fazla yanıt eklemek gerekli değil.
Afshin Mehrabani

7
@AfshinMehrabani belki korunabilir, kapatılamaz?
evolutionxbox

Yanıtlar:


1508

İfadenin düşme özelliğini kullanın switch. Eşleşen bir vaka, bir break(veya switchifadenin sonu ) bulunana kadar çalışır, böylece şöyle yazabilirsiniz:

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

   default: 
       alert('Default case');
}


2
Bir şekilde Chrome'da, javascript konsolunda benim için çalışıyor: switch('10') { case 1, '10': console.log('ok') }baskılarok
nafg

8
@nafg: Deneyin switch(1). Buradaki etiket sadece bir virgül ifadesidir.
kennytm

4
@Barney Hayır, ara vermeden bir sonraki davaya geçebilirsiniz.
Seiyria

1
@Seiyira tanım gereği, sonrakinden sonra bir sonraki dava yok. Ayrıca, bu bir varsayılan.
Barney

101

Bu normal JavaScript ile çalışır

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

Şerefe.


13
@believesInSanta, garip biçimlendirmeyle (yeni satırlar yerine boşluklar) kelimenin tam anlamıyla normal bir durum düşüşü
Mihail Malostanidis

42

İşte switchifadeden tamamen kaçınan farklı yaklaşım :

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

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

5
Bu versiyonu kesinlikle tercih ediyorum. Üzerinden düşmeye eğilimli bir özelliktir switch ... case. Bir breakifadeyi unutmak çok kolaydır ve bilerek düşmeyi kullanırsanız, unutulan bu breakifadeleri fark etmek çok zor olabilir. Bu yöntem arama sürümü switch ... case, dinamik genişletilebilirlik veya mod geçişini gerçekleştirmek için nesneyi tamamen değiştirme yeteneği gibi eksik birçok harika özelliğe sahiptir . Temiz bir şekilde düzenli tutmak da daha kolaydır ve daha sürdürülebilir bir koda yol açabilir. Bkz. Ericleads.com/2012/12/switch-case-considered-harmful
Eric Elliott

31
//fallthroughYerine her zaman bir yorum eklerimbreak kasıtlı olarak atladığım zamanbreak . Bu, ne zaman bir hata olduğunu ve ne zaman kasıtlı olduğunu tanımlamaya yardımcı olur.
Mnebuerquo

18
Sezgisel yaklaşım. Ancak, okunabilirlik için yerel anahtar deyimini kullanmanızı öneririm.
contactmatt

39
Bir kişi sağ elini boynunun arkasından geçirerek sol kulağı her zaman çizebilir ... Bu karmaşık çözüm lehine yapılacak doğru şey gibi görünmüyor ...)
Clint Eastwood

25
Bunun nasıl 34 oy aldığını görünce gerçekten şaşırdım. Okunabilirlik ve sürdürülebilirlik açısından bu kesinlikle korkunç. Hangi koşulların bir şeyi tetikleyeceğini görmek istersem, vaka bildirimi etiketlere bakarak inanılmaz derecede basit ve görülmesi kolaydır. Öte yandan, sürümünüz birisinin hemen hemen her satırı okumasını ve nereye atadığınızı görmesini gerektirir. Bu aynı zamanda eşleştirmek istediğiniz daha fazla vakayı daha da kötüleştirir.
michael

21

Bir anahtarda birden çok vaka atamak için Javascript'te, different case without break inbetweenaşağıdaki gibi tanımlamamız gerekir :

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

Lütfen örneğe bakınız linke tıklayın


5
Bir pletora dilinde yaygın bir tekniktir, JS'ye bağlı değildir
drAlberT

13

ES6 kullanıyorsanız bunu yapabilirsiniz:

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

Veya JavaScript'in önceki sürümleri için bunu yapabilirsiniz:

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

Bunun eski IE tarayıcılarda çalışmadığını, ancak işleri oldukça kolay bir şekilde kurabileceğinizi unutmayın. Daha fazla bilgi için dizenin javascript'te listede olup olmadığını belirleme konusuna bakın .


Bunun bir anahtar üzerinden ne faydası var?
Bryce Snyder

@BryceSnyder bir ifade ve ifade arasındaki fark? Daha az yazarak? Daha az dikey çizgi mi tüketiliyor? Özlü olma ve temsil yoğunluğu ile daha fazla ifade gücü? Kelimeyle daha iyi anlambilim includes? İstediğini al.
ErikE

7

Düğümde, bunu yapmanıza izin verildiği anlaşılıyor:

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

Bu, bazı durumlarda çok daha kompakt bir kod oluşturur.


1
Sözdiziminin diğer JS ortamlarıyla aynı olduğunu düşünüyorum.
Afshin Mehrabani

1
@AfshinMehrabani Belki de sadece nodejs bağlamında test ettim.
Automatico

Evet. Dikey yerden tasarruf etmeyi seviyorum!
kanal

7

Stefano'nun cevabını ekleyerek ve açıklığa kavuştururken, anahtardaki koşulların değerlerini dinamik olarak ayarlamak için ifadeleri kullanabilirsiniz, örneğin:

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

Yani probleminizde, şöyle bir şey yapabilirsiniz:

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

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

çok KURU olmasa da ..


henüz test edilmedi ancak varNamevaka ifadesinin içinde değişiklik yapmak ilginç olurdu , varName öğesinin önbelleğe alınmasını bekleyin.
Valen

5

kullanabilirsiniz. in ' operatörünü kullanabilirsiniz ...
nesneye / karma çağrısına dayanır ...
böylece javascript kadar hızlı olabilir ...

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

Keyfini çıkarın, ZEE


bunun geçiş ile nasıl bir ilişkisi var? açıklığa kavuşturabilir misin?
Z. Khullah

neden kodunuzu "okumayı zorlaştırmak" istiyorsunuz? Bir programcı olarak bana söylenen ilk şey, zihninizle kod yazmak, kodunuzu okuyan bir sonraki kişinin seri katili kullanan bir balta olduğunu ve kodu anlayamamaktan nefret etmekti.
MattE

Merhaba Matt ... Bunu bir konsept kanıtı olarak sunuyorum ... yine de bu form size daha fazla işlevsellik ve esneklik sağlıyor ... ve sadece isterseniz ... ya da bir kısıtlama bulursanız olağan şeyler yapmanın ... programcı araç
kutunuzda

5

Ben böyle kullanın:

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

gBayrağı kullanmanıza gerek yoktur , çünkü normal ifadeleri bir kez kullanır ve atarsınız. Aslında, bunları işlevin dışında tutarsanız, gbayrak sonraki .test(s'de 0 olmayan bir dizinden eşleştirmeye çalışarak size zarar verir . Ayrıca, anahtar kasasının sensordeğişken olduğu ve trueboole ifadelerinin eşleşmesi için sabit olmadığı bir yazım hatasını düzelttim . Düzenlemeye bakın.
Mihail Malostanidis

Bu biçimi dosya türlerine karşı test etmek için kullandım. Örn:case /officedocument/.test(type) && /presentation/.test(type): iconClass = "far fa-file-powerpoint red"; break;
tbone849

4

Değişir. Switch yalnızca bir kez değerlendirir. Bir maçın ardından, vaka ne olursa olsun, 'kırılana kadar devam eden tüm dava açıklamaları.

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

Açıklık ve KURU sözdizimi için bunu beğendim.

varName = "larry";

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

    default: 
       alert('Default case');

}

2

Burada birçok iyi yanıt olduğunu görebiliyorum, ancak 10'dan fazla vakayı kontrol etmemiz gerekirse ne olur? İşte benim kendi yaklaşımım:

 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
Bu, switch ifadesinin kötüye kullanılmasıdır. Sadece if (accessDenied.includes(varName)) return 'Access Denied!'; return 'Access Allowed.'fazlasıyla yeterli.
Mihail Malostanidis

2

Yukarıdaki yaklaşımlarla ilgili sorun, sahip caseolan işlevi her çağırdığınızda birkaç s'yi tekrarlamanız gerektiğidir switch. Daha sağlam bir çözüm, bir haritaya veya sözlüğe sahip olmaktır .

İşte bir örnek

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

Bunu yapabilirsiniz:

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

veya yalnızca tek bir kod satırı:

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

ErikE'nin cevabından biraz gelişme


1

Buraya yaşadığım benzer bir sorunla gelen herkese, haftalarca kodlama ve tükenmişlikten sonra karşılaştım, durumum benzer bir şeydi:

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

Her zaman defaultdava girildi. Benzer bir çok durumlu anahtar bildirimi sorunuyla karşılaşıyorsanız, aradığınız şey:

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

Umarım bu birine yardımcı olur, anahtar kasasını redux redüktörlerimde kullandığım gibi hatırlamadan önce saçlarımı çıkarıyordum.


0

Olası çözümlerden biri:

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

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

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

Q pls hangi # ecma bu?
BG Bruno

Merhaba. Bu ES6
Jackkobec

0

Benim için bu en basit yol:

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

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

-1

Bir fonksiyonun içindeyken switch deyiminde birden çok vaka yapmanın başka bir yolu

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


-2

Bunu şöyle yazabilirsiniz:

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

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

6
Bu herkesle aynı cevap, "unuttuğunuz, ancak bunu silmeyi düşünün" diye düzeltirim.
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>

3
klasik jquery dahil :)
ptim

4
Bu değil nasıl switchdeyim çalışması gerekiyordu. Sadece case "1":, değil case (num = "1"):.
user4642212

Neden gün değerini kasaya ve document.getElementById("result").innerHTML = ....anahtarın dışına koyup gün değeri sonucunu sonuna eklemiyorsunuz?
Steffo Dimfelt

@Xufox Kelimenin tam anlamıyla üzerine yazmayı seviyorum numama hala çalışıyor çünkü switchzaten değerlendirilmiş ve atama değeri veriyor . Bu en iyi mutasyon / makine öğrenimi ile programlamadır.
Mihail Malostanidis

-3

sadece anahtar durumu yaklaşımını değiştirin

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

2
Anahtar ifadesi olarak true değerini koyarsanız, "case" ifadelerinde, bir boole döndürmeniz koşuluyla istediğinizi değerlendirebilirsiniz
Stefano Favero

1
Kastettiği şey, işlevin içine, dava için dinamik bir değer değerlendirecek ve geri döndürecek bir ifade koyabileceğiniz, böylece her türlü karmaşık koşullara izin
verebileceğinizdir

Bu @StefanoFavero notu için sadece (expression)parantez içinde bir işleve ihtiyacınız yoktur ve dönüş değeri girdi olmalıdır. Cevabımı gör
Z. Khullah

neden çıkardınız ?? Bu çözümü savunuyorum çünkü karmaşık koşullar için esneklik sağlıyor. Funcs'ı koşul olarak beğenmeseniz bile, bunları sizinle birden fazla koşulla değiştirebilirsinizswitch(true) { case (var1 === 0 && var2 === true): {} }
AlexNikonov
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.