javascript: anahtar durumunda bir koşul kullanma


89

Aptalca soru için üzgünüm. JavaScript anahtar durumu dil öğesindeki bir durum için bir koşulu nasıl kullanabilirim? Aşağıdaki örnekte olduğu gibi, değişken liCount<= 5 ve> 0 olduğunda bir durum eşleşmelidir ; ancak kodum çalışmıyor:

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

Herhangi bir tavsiye için teşekkürler!


4
Bunu yapmak istiyorsanız yerine if ifadeleri kullanın ..
Naftali aka Neal

3
Herkesin size ifs kullanmanızı söyleyenleri görmezden gelmemelisiniz çünkü onlar haklılar. Bu korkunç bir uygulamadır switch.
lincolnk

Bu çözümün sağlanmadığına inanamıyorum. Bunu yapabilirsiniz, ifadenin sadece switch cümlesindeki değerle değerlendirilmesi gerekir. Yani bu işe yarayacak: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

Yanıtlar:


291

Bu çalışıyor:

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

Bu cevabın önceki bir versiyonu parantezlerin suçlu olduğunu düşünüyordu. Gerçekte, parantezler burada alakasızdır - gerekli olan tek şey switch(true){...}ve sizin durum ifadelerinizin boole'lere göre değerlendirilmesi.

Çalışır çünkü, anahtara verdiğimiz değer, karşılaştırmak için temel olarak kullanılır. Sonuç olarak, mantıksal değerlere göre değerlendirilen durum ifadeleri de hangi durumun çalıştırılacağını belirleyecektir. Bunu tersine çevirebilir ve geçebilir switch(false){..}ve istenen ifadelerin doğru yerine yanlış olarak değerlendirilmesini sağlayabilir .. ama kişisel olarak doğruluğu değerlendiren koşullarla uğraşmayı tercih edebilir. Ancak, o da işe yarıyor, bu yüzden ne yaptığını anlamak için akılda tutmaya değer.

Örneğin: liCount 3 ise, ilk karşılaştırma true === (liCount == 0), yani ilk durum yanlıştır. Anahtar daha sonra bir sonraki duruma geçer true === (liCount<=5 && liCount>0). Bu ifade, true olarak değerlendirilir, yani bu durum çalıştırılır ve break. Daha açık hale getirmek için buraya parantezler ekledim, ancak ifadenizin karmaşıklığına bağlı olarak isteğe bağlıdırlar.

Oldukça basit ve (eğer yapmaya çalıştığınız şeye uyuyorsa), belki de uzun bir seri ìf() ... else if() ... else if () ...çok fazla görsel gürültü veya kırılganlık getirebilecek uzun bir dizi koşulu idare etmenin düzgün bir yolu .

Geçerli kod olmasına rağmen standart olmayan bir model olduğundan dikkatli kullanın.


9
Sanırım sahip olmanız gerekecek switch(true) {, case liCount == 0:değil mi? Aksi takdirde bu karşılaştırma liCount == (liCount <=5 && liCount > 0).
loganfsmyth

33
Sen olduğundan değil, biliyorum can bunu gerektiği . Bu ateşle öldürülmesi gereken bir şey.
JBert

21
Bu dilin bir parçasıdır - sonuç olarak, onu bilmek, bilmemekten daha iyidir. Açıkçası, her durum için uygun olmayacaktır, ancak tamamen öznel bir düzeyde, bence bu ilginç bir yaklaşım ve bu durumda bir dizi ifs / elif'ten daha okunaklı / daha az kırılgan. Unutulmaması gereken önemli şey, kodlamanın zevk ve pratikle birlikte bir niyet ifadesi olduğudur. Kendinizi kodla açıkça ifade etmek için daha fazla seçeneğe sahip olmak asla kötü bir şey değildir.
dmp

1
Benim için bu, mantığımı, if koşuluna bağlı olarak tekrar tekrar bir değişken adı kullanmam gereken yerde düzenlemenin çok güzel bir yoluydu, ancak bu n + 1 tipi bir senaryoydu, bu nedenle bir mola aşağıdaki satıra geçecek kritik derecede yararlı oldu.
Joseph Astrahan

2
Hatta anahtar ifadesi bu kadar yanlışsa sonucun ne olacağını görmek için gözlerimizi switch(false) {
açtınız

24

Sen ettik yolu olduğunu overcomplicated. Bunun yerine if ifadeleri ile yazın:

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

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

Veya ChaosPandion mümkün olduğu kadar optimize etmeye çalışıyorsa:

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

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

Gidip benden biri olmak zorundaydın. :)
ChaosPandion

Yazılarımızı aynı anda yazdık. Seninkini gönderene kadar görmedim. Görünüşe göre şimdi abartıyorsun ...
Eric

Vay canına, aşırı karmaşık koşul ifadeleri hakkında gerçekten düşünmedim.
ChaosPandion

1
@Chaos: evet, muhtemelen abartıyor. Şuna da bir null-check eklemeniz gerekir setLayoutState: P.
Eric

@Eric - bazı programcılar benim söylediğimden daha fazla programlama turu olan bazı programcılar: "Javascript'i parantez olmadan yazabilmeniz (ve - aslında dikkatlice - noktalı virgülle) yapmanız gerektiği anlamına gelmez", Ama ben sadece birkaçını yeniden yazdım eğer ifadeler yine de örneğinizdeki gibi, bu yüzden teşekkürler - koşuldan sonra çalıştırılacak birden fazla satır olana kadar sorunsuz çalışır. Üçlü çözüm benim için çok uzak bir köprüdü, yine de…
Dave Everitt

7

İf ifadelerini kullanmak istiyorsunuz:

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

7

Aşağıdaki dmp'nin cevabına bakın. Yapabilseydim bu cevabı silerdim, ama kabul edildi, bu yüzden bu sonraki en iyi şey :)

Yapamazsın. JS Interpreters, switch ifadesiyle karşılaştırmanızı ister (örneğin, "case when" ifadesi yoktur). Bunu gerçekten yapmak istiyorsanız, sadece if(){ .. } else if(){ .. }bloklar yapabilirsiniz .


9
Bu yanlış. İşte çalıştığını gösteren bir demo: jsfiddle.net/Ender/fr3wL . ECMAScript standardı, buna izin verildiğini açıkça belirtir: docstore.mik.ua/orelly/webprog/jscript/ch06_05.htm#FOOTNOTE-18
Ender

3
@Ender Haemse'nin yapmaya çalıştığı şey nasıl oluyor?
Aistina

@Aistina değil. Vaka koşulları sayısal bir değerden çok doğru / yanlış bir değer ürettiğinden, haemse'nin sayısal değerine karşı test etmek yerine vakalarını doğru bir değer için (danp'ın cevabının önerdiği gibi) test etmesi gerekecekti liCount. Ben sadece cwolves orijinal ifadesinin "JS Yorumlayıcılarının durum ifadelerinin statik değerler olmasını gerektirir" ifadesinin yanlış olduğuna işaret ediyordum. cwolves o zamandan beri bu açıklamayı revize etti, bu nedenle yorumum artık geçerli değil.
Ender

Çünkü bu soruya cevap vermiyor. Bunu yapmanın farklı bir yolunu istemedi, değiştirme durumunun istediği gibi çalışmasını istedi. "Başka bir şekilde yap", neredeyse her zaman öyle olduğunu düşünmemize rağmen, neredeyse hiçbir zaman doğru bir cevap değildir. Her zaman daha iyi bir yolumuz olduğunu düşünüyoruz, ama bu onun istediği şey değil, bu yanıtı tamamen yanlış yapıyor.
Jasmine

@Yasemin - "Yapamazsın, başka türlü yap" , doğruysa tamamen geçerlidir . Cevabım aşağı oylanıyor çünkü bu çok yanlış :) @danp'ın da belirttiği gibi, sadece geçiş yapabilirsiniz trueve işe yarıyor. Ama 3 yaşın üzerinde, bu yüzden gerçekten umrumda değil.
Mark Kahn

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

koşullarınız uygun booleandeğerleri döndürdüğü sürece JavaScript'te çalışacaktır , ancak else ififadelere göre pek çok avantajı yoktur .


10Switch deyiminde bir tamsayı sayarsam işe yarayacak mı? benim durumumda çalışmama sebebinin ne olduğundan emin değilim.
Pardeep Jain

10 !== trueyani hayır. Değeri olabilecek bir değişken var 10mı? Eğer x, o case x === 10:zaman işe yarar.
Mike Samuel

Ancak diğer ifadeler gibi çalışmalıdır, örneğin if (10) {..}akış kullanıyorsanız , Ifkoşulda geçmek gerekir , değil mi? çünkü 10 veya 0 dışında herhangi bir tam sayı doğru değer olarak kabul edilecek ve koşula girilmesine izin verecektir. Burada ifadeyi değiştirmesinin neyin yanlış olduğundan emin değilim.
Pardeep Jain

1
@PardeepJain, switchbasitçe çalışmıyor if. ifdurumun doğru olup olmadığını test eder . switchsonra ekspresyon olsun test switcholan ===( CaseClauseIsSelected aşama 4 sonra ifade değerine) case.
Mike Samuel

Ohh böyle, teşekkürler. Bu benim için tamamen yeniydi. @Mike
Jain


4

Eğer yapmak istediğiniz buysa, ififadeler kullanmak daha iyi olacaktır . Örneğin:

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

Kodunuz çalışmıyor çünkü yapmasını beklediğiniz şeyi yapmıyor. Anahtar blokları bir değer alır ve her durumu verilen değerle karşılaştırarak eşitliği arar. Karşılaştırma değeriniz bir tam sayıdır, ancak durum ifadelerinizin çoğu bir boole değerine dönüşür.

Örneğin, diyelim liCount = 2. İlk davanız eşleşmeyecek çünkü 2 != 0. İkinci vakanız olarak (liCount<=5 && liCount>0)değerlendirilir true, ancak 2 != truebu nedenle bu vaka da eşleşmeyecektir.

Bu nedenle, diğerlerinin de söylediği gibi, bunu if...then...else ifyapmak için bir dizi blok kullanmalısınız .


2

olası değerler tam sayı ise, vakaları gruplayabilirsiniz. Aksi takdirde, ifs kullanın.

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

Değişime puan vermediğimize, ancak doğru olduğuna dikkat edin. Anahtara verdiğimiz değer, karşılaştırmak için temel olarak kullanılır.

Aşağıdaki örnek, vakaya nasıl koşul ekleyebileceğimizi gösterir: if ifadesi olmadan.

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'nin sorusunun belirli bir örneğinde switchuygun olmasa da, geçişin hala uygun / faydalı olduğu bir örnek vardır, ancak başka değerlendirme ifadeleri de gereklidir. Bu, ifadeler için varsayılan cümle kullanılarak elde edilebilir:

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

Geçiş durumunda düşme yöntemini kullanabilirsiniz.

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