javascript: ใช้เงื่อนไขในกรณีสวิตช์


89

ขออภัยสำหรับคำถามโง่ ๆ ฉันจะใช้เงื่อนไขสำหรับเคสในเอลิเมนต์ภาษาสวิตช์ของจาวาสคริปต์ได้อย่างไร เช่นเดียวกับตัวอย่างด้านล่างกรณีควรจับคู่เมื่อตัวแปร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 aka Neal

3
คุณไม่ควรเพิกเฉยต่อทุกคนที่บอกให้คุณใช้ifs เพราะถูกต้อง switchนี้เป็นโปรแกรมที่น่ากลัวของ
lincolnk

ฉันไม่อยากจะเชื่อเลยว่าไม่มีวิธีแก้ปัญหานี้ คุณสามารถทำได้คำสั่งเพียงแค่ต้องการประเมินค่าในประโยคสวิตช์ สิ่งนี้จะได้ผล: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

คำตอบ:


291

ใช้งานได้:

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)หมายความว่ากรณีแรกเป็นเท็จ true === (liCount<=5 && liCount>0)สวิทช์แล้วย้ายไปกรณีต่อไป นิพจน์นี้ประเมินค่าเป็นจริงหมายความว่าเคสนี้ถูกรันและสิ้นสุดที่ไฟล์break. ฉันได้เพิ่มวงเล็บที่นี่เพื่อให้ชัดเจนขึ้น แต่เป็นทางเลือกขึ้นอยู่กับความซับซ้อนของนิพจน์ของคุณ

มันค่อนข้างง่ายและเป็นวิธีที่เรียบร้อย (ถ้ามันเข้ากับสิ่งที่คุณพยายามจะทำ) ในการจัดการกับเงื่อนไขที่ยาวนานซึ่งบางทีชุดยาวìf() ... else if() ... else if () ...อาจทำให้เกิดสัญญาณรบกวนหรือความเปราะบางในภาพ

ใช้ด้วยความระมัดระวังเนื่องจากเป็นรูปแบบที่ไม่ได้มาตรฐานแม้ว่าจะเป็นรหัสที่ถูกต้องก็ตาม


9
ฉันคิดว่าคุณจะต้องมีswitch(true) {และcase liCount == 0:ใช่มั้ย? liCount == (liCount <=5 && liCount > 0)มิฉะนั้นการเปรียบเทียบนี้คือ
loganfsmyth

33
คุณจะรู้ว่ามันไม่ได้เพราะคุณสามารถที่คุณควร นี่คือสิ่งที่ต้องฆ่าด้วยไฟ
JBert

21
มันเป็นส่วนหนึ่งของภาษา - ดังนั้นการรู้เรื่องนี้จะดีกว่าไม่ เห็นได้ชัดว่ามันคงไม่เหมาะสมกับทุกสถานการณ์ แต่ในระดับอัตวิสัยล้วนๆฉันคิดว่านี่เป็นแนวทางที่น่าสนใจและอ่านง่าย / เปราะบางน้อยกว่าชุด ifs / elif ในกรณีนี้ สิ่งสำคัญที่ต้องจำไว้คือการเขียนโค้ดเป็นการแสดงเจตนาควบคู่ไปกับรสนิยมและการฝึกฝน การมีตัวเลือกเพิ่มเติมในการแสดงความเป็นตัวเองอย่างชัดเจนในรหัสไม่ใช่เรื่องเลวร้าย
dmp

1
สำหรับฉันสิ่งนี้มีประโยชน์มากและเป็นวิธีที่ดีมากในการจัดระเบียบตรรกะของฉันที่ฉันต้องใช้ชื่อตัวแปรซ้ำแล้วซ้ำอีกตามเงื่อนไข if แต่มันเป็นสถานการณ์ประเภท n + 1 ดังนั้นความจริงที่ว่าสลับกรณีคำสั่งโดยไม่มี การหยุดพักจะย้ายไปยังบรรทัดถัดไปด้านล่างมีประโยชน์อย่างยิ่ง
Joseph Astrahan

2
คุณยังเปิดตาของเราเพื่อดูว่าผลลัพธ์จะเป็นอย่างไรหากการแสดงออกของสวิตช์เป็นเท็จเช่นนั้น switch(false) { }
bello hargbola

24

คุณมีวิธีที่ซับซ้อนมากเกินไป เขียนด้วย if statement แทนดังนี้:

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

คุณต้องไปและขึ้นกับฉัน :)
ChaosPandion

เราเขียนโพสต์ของเราพร้อมกัน ฉันไม่เห็นของคุณจนกว่าฉันจะโพสต์ไปแล้ว ดูเหมือนตอนนี้คุณจะหักโหมเกินไปแล้ว ...
Eric

ว้าวฉันไม่ได้คิดถึงเงื่อนไขที่ซับซ้อนเกินไป
ChaosPandion

1
@ Chaos: ใช่นั่นอาจจะหักโหมเกินไป คุณต้องเพิ่ม null-check setLayoutStateด้วย: P.
Eric

@Eric - โปรแกรมเมอร์บางคนที่มีรอบการเขียนโปรแกรมใต้เข็มขัดมากกว่าที่ฉันพูด: "เพียงเพราะคุณสามารถเขียน Javascript ได้โดยไม่ต้องจัดฟัน (และ - ในความเป็นจริงด้วยความระมัดระวัง - อัฒภาค) ไม่ได้หมายความว่าคุณควร" แต่ฉันเขียนซ้ำบางส่วน ถ้าคำสั่งในตัวอย่างของคุณอย่างไรก็ตามขอบคุณ - ใช้งานได้ดีจนกว่าจะมีมากกว่าหนึ่งบรรทัดเพื่อดำเนินการหลังจากเงื่อนไข วิธีแก้ปัญหาเล็กน้อยเป็นสะพานที่ไกลเกินไปสำหรับฉันแม้ว่า…
Dave Everitt

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 Interpreters ต้องการให้คุณเปรียบเทียบกับคำสั่ง switch (เช่นไม่มีคำสั่ง "case when") หากคุณต้องการทำสิ่งนี้จริงๆคุณสามารถสร้างif(){ .. } else if(){ .. }บล็อกได้


9
ไม่ถูกต้อง นี่คือการสาธิตการแสดงการทำงาน: jsfiddle.net/Ender/fr3wL มาตรฐาน ECMAScript อย่างชัดเจนว่าเรื่องนี้จะได้รับอนุญาต: docstore.mik.ua/orelly/webprog/jscript/ch06_05.htm#FOOTNOTE-18
พลิก

3
@Ender มันเหมือนกับสิ่งที่ haemse พยายามจะทำยังไง?
Aistina

@Aistina มันไม่ใช่ เนื่องจากเงื่อนไขกรณีของเขาผลิตจริงค่า / เท็จมากกว่าค่าตัวเลข, haemse จะมีความจำเป็นในการทดสอบกรณีของเขาสำหรับค่า truthy (เช่นการแนะนำโดยคำตอบของ danp) liCountมากกว่าการทดสอบกับค่าตัวเลขของ ฉันเป็นเพียงการชี้ให้เห็นว่าคำสั่งเดิมที่ระบุว่า "JS Interpreters ต้องการให้ประโยค case เป็นค่าคงที่" นั้นไม่ถูกต้อง cwolves ได้แก้ไขข้อความนี้แล้วดังนั้นความคิดเห็นของฉันจึงไม่เกี่ยวข้องอีกต่อไป
พลิก

เพราะสิ่งนี้ไม่ตอบโจทย์. เขาไม่ได้ขอวิธีอื่นในการทำเขาขอให้สวิตช์เคสทำงานอย่างที่เขาต้องการ "ทำวิธีอื่น" แทบจะไม่เคยเป็นคำตอบที่ถูกต้องเลยทั้งๆที่เรามักจะคิดว่ามันเป็นอย่างนั้น เราคิดเสมอว่าเรามีวิธีที่ดีกว่า แต่นั่นไม่ใช่วิธีที่เขาต้องการทำให้คำตอบนี้ผิดไปจากเดิม
จัสมิน

@Jasmine - "คุณไม่สามารถเพื่อทำมันบางวิธีอื่น ๆ" ที่ถูกต้องสมบูรณ์ถ้ามันถูกต้อง คำตอบของฉันคือการโหวตลดลงเพราะมันผิด :) ตามที่ @danp ชี้ให้เห็นคุณสามารถสลับไปมาtrueและใช้งานได้ แต่มันเกิน 3 ปีแล้วดังนั้นฉันไม่สนใจจริงๆ
Mark Kahn

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

จะทำงานใน JavaScript ตราบเท่าที่เงื่อนไขของคุณส่งคืนbooleanค่าที่เหมาะสมแต่ก็ไม่มีข้อดีมากกว่าelse ifคำสั่ง


จะใช้งานได้หรือไม่ถ้าฉันส่งจำนวนเต็มพูด10ในคำสั่ง switch? ในกรณีของฉันไม่ทำงานไม่แน่ใจว่าอะไรเป็นสาเหตุ
Pardeep Jain

10 !== trueดังนั้นไม่ มีตัวแปรบางตัวที่อาจมีค่า10หรือไม่? ถ้าเป็นxเช่นนั้นcase x === 10:จะทำงาน
Mike Samuel

แต่มันควรจะทำงานเหมือนคำสั่งอื่น ๆ เช่นถ้าคุณใช้if (10) {..}flow ก็ควรผ่านIfเงื่อนไขไม่ใช่หรือ? เนื่องจาก 10 หรือจำนวนเต็มยกเว้น 0 จะถือว่าเป็นค่าที่แท้จริงและอนุญาตให้เข้าสู่เงื่อนไข ไม่แน่ใจว่ามีอะไรผิดปกติกับเขาเปลี่ยนคำสั่งที่นี่
Pardeep Jain

1
@PardeepJain, เพียงไม่ทำงานเช่น switch ทดสอบว่าสภาพจริงหรือไม่ ทดสอบว่านิพจน์หลังเป็น( CaseClauseIsSelected ขั้นตอนที่ 4 ) เป็นค่าของนิพจน์หลังหรือไม่ ififswitchswitch===case
Mike Samuel

โอ้เช่นนั้นขอบคุณ นี่เป็นเรื่องใหม่สำหรับฉันโดยสิ้นเชิง @Mike
Pardeep Jain


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กรณีแรกของคุณจะไม่ตรงเพราะ กรณีที่สองของคุณ(liCount<=5 && liCount>0)ประเมินเป็นtrueแต่2 != 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

สังเกตว่าเราไม่ผ่านคะแนนไปที่สวิตช์ แต่เป็นจริง ค่าที่เราให้กับสวิตช์ถูกใช้เป็นพื้นฐานในการเปรียบเทียบ

ตัวอย่างด้านล่างแสดงให้เห็นว่าเราสามารถเพิ่มเงื่อนไขในกรณีได้อย่างไร: โดยไม่มีคำสั่ง 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

แม้ว่าในตัวอย่างคำถามของ 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
    }
}

0

คุณสามารถใช้วิธี fall-through ในกรณีเปลี่ยน

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.