javascript: sử dụng một điều kiện trong trường hợp chuyển đổi


88

Xin lỗi vì câu hỏi ngu ngốc đó. Làm cách nào để sử dụng điều kiện cho một trường hợp trong phần tử ngôn ngữ chuyển đổi-trường hợp của javascript? Giống như trong ví dụ bên dưới, một trường hợp phải khớp khi biến liCount<= 5 và> 0; tuy nhiên, mã của tôi không hoạt động:

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

Cảm ơn vì bất kỳ lời khuyên!


4
sử dụng nếu phát biểu thay vì nếu u muốn làm điều đó ..
Naftali aka Neal

3
Bạn không nên phớt lờ mọi người bảo bạn sử dụng ifs, vì họ đúng. Đây là một ứng dụng khủng khiếp của switch.
lincolnk

Tôi không thể tin rằng giải pháp này đã không được cung cấp. Bạn có thể làm điều này, câu lệnh chỉ cần đánh giá đến giá trị trong mệnh đề switch. Vì vậy, điều này sẽ hoạt động: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

Câu trả lời:


286

Những công việc này:

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

Phiên bản trước của câu trả lời này coi dấu ngoặc đơn là thủ phạm. Trên thực tế, dấu ngoặc đơn không liên quan ở đây - điều duy nhất cần thiết là switch(true){...}và để các biểu thức trường hợp của bạn đánh giá thành boolean.

Nó hoạt động bởi vì, giá trị chúng tôi cung cấp cho công tắc được sử dụng làm cơ sở để so sánh với. Do đó, các biểu thức trường hợp, cũng được đánh giá thành boolean sẽ xác định trường hợp nào được chạy. Cũng có thể xoay chuyển điều này, và vượt qua switch(false){..}và có các biểu thức mong muốn được đánh giá thành sai thay vì đúng .. nhưng cá nhân tôi thích xử lý các điều kiện đánh giá tính trung thực. Tuy nhiên, nó cũng hoạt động, vì vậy cần ghi nhớ để hiểu những gì nó đang làm.

Ví dụ: nếu liCount là 3, so sánh đầu tiên là true === (liCount == 0), nghĩa là trường hợp đầu tiên là sai. Sau đó, công tắc chuyển sang trường hợp tiếp theo true === (liCount<=5 && liCount>0). Biểu thức này đánh giá là true, nghĩa là trường hợp này được chạy và kết thúc tại break. Tôi đã thêm dấu ngoặc đơn ở đây để làm rõ ràng hơn, nhưng chúng là tùy chọn, tùy thuộc vào mức độ phức tạp của biểu thức của bạn.

Nó khá đơn giản và là một cách gọn gàng (nếu nó phù hợp với những gì bạn đang cố gắng làm) để xử lý một loạt điều kiện dài, trong đó có lẽ một loạt điều kiện dài ìf() ... else if() ... else if () ...có thể gây ra nhiều nhiễu hình ảnh hoặc độ mỏng manh.

Hãy sử dụng một cách thận trọng, vì đây là một mẫu không chuẩn, mặc dù là mã hợp lệ.


9
Tôi nghĩ bạn cần phải có switch(true) {, và case liCount == 0:phải không? Nếu không thì so sánh này là liCount == (liCount <=5 && liCount > 0).
loganfsmyth

33
Bạn biết đấy, không phải vì bạn có thể mà bạn nên làm như vậy . Đây là thứ cần phải giết bằng lửa.
JBert

21
Đó là một phần của ngôn ngữ - do đó, biết về nó sẽ tốt hơn là không. Rõ ràng, nó sẽ không phù hợp cho mọi tình huống, nhưng ở mức độ hoàn toàn chủ quan, tôi nghĩ đây là một cách tiếp cận thú vị và dễ đọc hơn / ít mong manh hơn một loạt ifs / elifs trong trường hợp này. Điều quan trọng cần nhớ là viết mã là sự thể hiện ý định, đi đôi với sở thích và thực hành. Có nhiều lựa chọn hơn để thể hiện rõ ràng bản thân bằng mã không bao giờ là một điều xấu.
dmp

1
Đối với tôi, điều này rất hữu ích và là một cách rất hay để tổ chức logic của tôi, nơi tôi cần sử dụng tên biến nhiều lần dựa trên điều kiện if, nhưng đó là một kịch bản loại n + 1 nên thực tế là trường hợp câu lệnh switch không có ngắt sẽ chuyển sang dòng tiếp theo bên dưới rất hữu ích.
Joseph Astrahan

2
Bạn thậm chí có mở mắt của chúng tôi để xem những gì kết quả sẽ có được nếu các biểu hiện chuyển đổi là sai như vậy switch(false) { }
bello hargbola

24

Bạn đã cách overcomplicated đó. Viết nó bằng câu lệnh if thay thế như thế này:

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

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

Hoặc, nếu ChaosPandion đang cố gắng tối ưu hóa nhiều nhất có thể:

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

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

Bạn phải đi và nâng tôi lên. :)
ChaosPandion

Chúng tôi đã viết các bài đăng của chúng tôi đồng thời. Tôi không thấy của bạn cho đến khi tôi đã đăng. Bây giờ bạn có vẻ đang làm quá mức ...
Eric

Chà, tôi không thực sự nghĩ về các điều kiện quá phức tạp.
ChaosPandion

1
@Chaos: vâng, đó có thể là làm quá mức. Bạn cũng sẽ phải thêm một dấu kiểm vào setLayoutState: P.
Eric

@Eric - một số lập trình viên có nhiều vòng lập trình hơn tôi đã nói: "chỉ vì bạn có thể viết Javascript mà không cần dấu ngoặc nhọn (và - thực tế là có cẩn thận - dấu chấm phẩy) không có nghĩa là bạn nên", nhưng tôi chỉ viết lại một số câu lệnh if như trong ví dụ của bạn, vì vậy, cảm ơn - hoạt động tốt cho đến khi có nhiều hơn một dòng để thực thi sau điều kiện. Các giải pháp ternary là một cây cầu quá xa đối với tôi, mặc dù ...
Dave Everitt

7

Bạn muốn sử dụng câu lệnh if:

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

7

Xem câu trả lời của dmp bên dưới. Tôi sẽ xóa câu trả lời này nếu tôi có thể, nhưng nó đã được chấp nhận vì vậy đây là điều tốt nhất tiếp theo :)

Bạn không thể. Trình thông dịch JS yêu cầu bạn so sánh với câu lệnh switch (ví dụ: không có câu lệnh "case when"). Nếu bạn thực sự muốn làm điều này, bạn chỉ có thể tạo if(){ .. } else if(){ .. }khối.


9
Điều đó không chính xác. Đây là bản demo cho thấy nó đang hoạt động: jsfiddle.net/Ender/fr3wL . Tiêu chuẩn ECMAScript tuyên bố rõ ràng rằng điều này được phép: docstore.mik.ua/orelly/webprog/jscript/ch06_05.htm#FOOTNOTE-18
Ender

3
@Ender Điều đó có giống với những gì haemse đang cố gắng thực hiện không?
Aistina

@Aistina Nó không phải. Vì các điều kiện trường hợp của anh ta tạo ra một giá trị đúng / sai chứ không phải là một giá trị số, có vẻ như sẽ cần phải kiểm tra các trường hợp của anh ta để tìm một giá trị trung thực (chẳng hạn như được đề xuất bởi câu trả lời của danp), thay vì thử nghiệm với giá trị số của liCount. Tôi chỉ đơn thuần chỉ ra rằng tuyên bố ban đầu của cwolves rằng "Trình thông dịch JS yêu cầu các câu lệnh trường hợp là giá trị tĩnh" là không chính xác. cwolves đã sửa đổi tuyên bố này, vì vậy nhận xét của tôi không còn phù hợp nữa.
Ender

Bởi vì điều này không trả lời câu hỏi. Anh ấy không yêu cầu một cách khác để làm điều đó, anh ấy yêu cầu làm cho trường hợp chuyển mạch hoạt động như anh ấy muốn. "Làm theo cách khác" hầu như không bao giờ là một câu trả lời chính xác mặc dù chúng ta luôn nghĩ là như vậy. Chúng tôi luôn nghĩ rằng mình có cách tốt hơn, nhưng đó không phải là cách anh ấy muốn làm, khiến câu trả lời này hoàn toàn sai.
Jasmine

@Jasmine - "Bạn không thể, vì vậy hãy làm theo cách khác" là hoàn toàn hợp lệ, nếu nó là chính xác . Câu trả lời của tôi đang bị bỏ phiếu vì nó sai :) Như @danp đã chỉ ra, bạn chỉ có thể chuyển đổi truevà nó hoạt động. Nhưng nó hơn 3 tuổi rồi nên tôi cũng không quan tâm lắm.
Mark Kahn

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

sẽ hoạt động trong JavaScript miễn là các điều kiện của bạn trả về các booleangiá trị thích hợp , nhưng nó không có nhiều lợi thế so với các else ifcâu lệnh.


Nó sẽ hoạt động Nếu tôi chuyển một số số nguyên nói 10trong câu lệnh switch? trong trường hợp của tôi không hoạt động không chắc chắn lý do là gì.
Pardeep Jain

10 !== true, vì vậy không. Có một số biến có thể có giá trị 10không? Nếu x, sau đó case x === 10:sẽ làm việc.
Mike Samuel

Nhưng nó sẽ hoạt động giống như các câu lệnh khác, ví dụ nếu bạn sử dụng if (10) {..}flow should pass trong Ifđiều kiện, phải không? bởi vì 10 hoặc bất kỳ số nguyên nào ngoại trừ 0 sẽ được coi là giá trị trung thực và cho phép nhập vào điều kiện. Không chắc có gì sai với anh ta chuyển tuyên bố ở đây.
Pardeep Jain

1
@PardeepJain, switchchỉ đơn giản là không hoạt động như thế nào if. ifkiểm tra xem điều kiện là trung thực . switchkiểm tra xem biểu thức sau switch===( CaseClauseIsSelected bước 4 ) với giá trị của biểu thức sau case.
Mike Samuel

Ohh như vậy, Cảm ơn. Điều này hoàn toàn mới đối với tôi. @ Mike
Pardeep Jain

4

Đó là một trường hợp mà bạn nên sử dụng ifmệnh đề.


4

Nếu đó là những gì bạn muốn làm, sẽ tốt hơn nếu sử dụng các ifcâu lệnh. Ví dụ:

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

Mã của bạn không hoạt động bởi vì nó không làm những gì bạn mong đợi. Các khối chuyển đổi nhận một giá trị và so sánh từng trường hợp với giá trị đã cho, tìm kiếm sự bình đẳng. Giá trị so sánh của bạn là một số nguyên, nhưng hầu hết các biểu thức trường hợp của bạn giải quyết thành giá trị boolean.

Vì vậy, ví dụ, nói liCount = 2. Trường hợp đầu tiên của bạn sẽ không phù hợp, bởi vì 2 != 0. Trường hợp thứ hai của bạn, (liCount<=5 && liCount>0)đánh giá true, nhưng 2 != true, vì vậy trường hợp này cũng sẽ không khớp.

Vì lý do này, như nhiều người khác đã nói, bạn nên sử dụng một loạt các if...then...else ifkhối để làm điều này.


2

nếu các giá trị có thể là số nguyên, bạn có thể tập hợp các trường hợp. Nếu không, hãy sử dụng 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

Lưu ý rằng chúng tôi không chuyển điểm cho công tắc nhưng đúng. Giá trị chúng tôi cung cấp cho công tắc được sử dụng làm cơ sở để so sánh với.

Ví dụ dưới đây cho thấy cách chúng ta có thể thêm điều kiện trong trường hợp: mà không có bất kỳ câu lệnh if nào.

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

Mặc dù trong ví dụ cụ thể về câu hỏi của OP, switchlà không phù hợp, có một ví dụ mà switch vẫn phù hợp / có lợi, nhưng cũng cần có các biểu thức đánh giá khác. Điều này có thể đạt được bằng cách sử dụng mệnh đề mặc định cho các biểu thức:

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
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.