Chuyển đổi câu lệnh nhiều trường hợp trong JavaScript


768

Tôi cần nhiều trường hợp trong câu lệnh chuyển đổi trong JavaScript, đại loại như:

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

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

Làm thế nào tôi có thể làm điều đó? Nếu không có cách nào để làm một cái gì đó như thế trong JavaScript, tôi muốn biết một giải pháp thay thế cũng theo khái niệm DRY .


5
Để một người bỏ phiếu để đóng câu hỏi này. Nó đã hơn 5 tuổi và có một câu trả lời được tích lũy - tại sao lại bỏ phiếu chặt chẽ?
lướt sóng

@surfmugg vì không cần thiết phải thêm câu trả lời.
Afshin Mehrabani

7
@AfshinMehrabani có lẽ nó có thể được bảo vệ, không bị đóng cửa?
Evolutionxbox

Câu trả lời:


1510

Sử dụng tính năng thông qua của switchtuyên bố. Một trường hợp phù hợp sẽ chạy cho đến khi tìm thấy break(hoặc kết thúc switchcâu lệnh), vì vậy bạn có thể viết nó như sau:

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

   default: 
       alert('Default case');
}


2
Bằng cách nào đó, nó hoạt động với tôi trong Chrome, trong bảng điều khiển javascript: switch('10') { case 1, '10': console.log('ok') }printok
nafg

8
@nafg: Hãy thử switch(1). Nhãn ở đây chỉ là một biểu thức dấu phẩy.
kennytm

4
@Barney Không, không có giờ nghỉ bạn có thể rơi vào trường hợp tiếp theo.
Seiyria

1
@Seiyira theo định nghĩa, không có trường hợp tiếp theo sau lần cuối cùng. Bên cạnh đó, nó là một mặc định.
Barney

101

Điều này hoạt động trong JavaScript thường xuyên

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

Chúc mừng.


13
@ BeliefInSanta theo nghĩa đen chỉ là trường hợp rơi vào trường hợp bình thường với định dạng kỳ lạ (khoảng trắng thay vì dòng mới)
Mihail Malostanidis

42

Đây là cách tiếp cận khác nhau để tránh switchtuyên bố hoàn toàn:

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

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

5
Tôi chắc chắn thích phiên bản này. Rơi qua là một tính năng dễ bị lỗi của switch ... case. Thật quá dễ dàng để quên một breaktuyên bố và nếu bạn sử dụng một cách có chủ ý, những breaktuyên bố bị lãng quên đó có thể rất khó phát hiện ra. Phiên bản tra cứu phương thức này cũng có rất nhiều tính năng tuyệt vời switch ... casethiếu, chẳng hạn như khả năng mở rộng động hoặc khả năng thay thế hoàn toàn đối tượng để thực hiện chuyển đổi chế độ. Việc giữ tổ chức sạch sẽ cũng dễ dàng hơn và có thể dẫn đến mã dễ bảo trì hơn. Xem ericleads.com/2012/12/switch-case-considered-harmful
Eric Elliott

31
Tôi luôn thêm một bình luận //fallthroughthay cho breakbất cứ khi nào tôi cố tình bỏ qua break. Điều đó giúp xác định khi nào đó là một sai lầm và khi đó là cố ý.
Mnebuerquo

18
Cách tiếp cận trực quan. Tuy nhiên, để dễ đọc, tôi khuyên bạn nên sử dụng câu lệnh chuyển đổi gốc.
contactmatt

39
Người ta luôn có thể gãi tai trái qua tay phải qua gáy ... (xin lỗi vì tiếng Anh của tôi, ý tôi là: "người ta luôn có thể làm phức tạp mọi thứ nhiều nhất có thể ... trong trường hợp này, tránh câu lệnh chuyển đổi ủng hộ giải pháp phức tạp này dường như không phải là điều nên làm ...)
Clint Eastwood

25
Tôi thực sự ngạc nhiên khi điều này đã nhận được 34 phiếu bầu. Về khả năng đọc và bảo trì, điều này là hoàn toàn khủng khiếp. Nếu tôi muốn xem những điều kiện nào sẽ kích hoạt một cái gì đó, một tuyên bố trường hợp cực kỳ đơn giản và dễ nhìn bằng cách nhìn vào các nhãn. Mặt khác, phiên bản của bạn sẽ yêu cầu ai đó đọc khá nhiều từng dòng và xem những gì bạn được chỉ định ở đâu. Điều này thậm chí còn tồi tệ hơn khi nhiều trường hợp bạn muốn khớp.
michael

21

Trong Javascript để gán nhiều trường hợp trong một chuyển đổi, chúng ta phải xác định different case without break inbetweennhư được đưa ra dưới đây:

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

Vui lòng xem ví dụ nhấp vào liên kết


5
Đây là một kỹ thuật phổ biến trong rất nhiều ngôn ngữ, không bị ràng buộc với JS
drAlberT

13

Nếu bạn đang sử dụng ES6, bạn có thể làm điều này:

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

Hoặc đối với các phiên bản trước của JavaScript, bạn có thể làm điều này:

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

Lưu ý rằng điều này sẽ không hoạt động trong các trình duyệt IE cũ hơn, nhưng bạn có thể vá mọi thứ khá dễ dàng. Xem câu hỏi xác định xem chuỗi có trong danh sách trong javascript để biết thêm thông tin không.


Lợi ích của việc này trên một công tắc là gì?
Bryce Snyder

@BryceSnyder sự khác biệt giữa một biểu thức và một tuyên bố? Ít gõ? Ít đường thẳng tiêu thụ hơn? Sức mạnh biểu cảm lớn hơn thông qua sự cô đọng và mật độ đại diện? Ngữ nghĩa tốt hơn thông qua các includestừ? Bạn chọn đi.
ErikE

7

Trong nút có vẻ như bạn được phép làm điều này:

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

Điều này làm cho mã nhỏ gọn hơn nhiều trong một số trường hợp.


1
Tôi nghĩ cú pháp giống như các môi trường JS khác.
Afshin Mehrabani

1
@AfshinMehrabani Có thể, tôi chỉ thử nghiệm nó trong bối cảnh của nodejs.
Automatico

Đúng. Tôi thích tiết kiệm không gian dọc!
Kênh

7

Thêm và làm rõ câu trả lời của Stefano, bạn có thể sử dụng các biểu thức để đặt các giá trị cho các điều kiện trong chuyển đổi, ví dụ:

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

Vì vậy, trong vấn đề của bạn, bạn có thể làm một cái gì đó như:

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

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

mặc dù không được nhiều DRY ..


chưa được thử nghiệm nhưng sẽ rất thú vị khi sửa đổi varNamebên trong biểu thức trường hợp, mong rằng varName được lưu trong bộ nhớ cache.
Valen

5

bạn có thể sử dụng toán tử ' in ' ...
dựa vào lời gọi đối tượng / hàm băm ...
để nó nhanh như javascript có thể ...

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

Thưởng thức, ZEE


Làm thế nào điều này liên quan đến chuyển đổi? bạn có thể làm rõ nó?
Z. Khullah

tại sao bạn muốn làm cho mã của bạn "khó đọc". Điều đầu tiên tôi được nói với tư cách là một lập trình viên là viết mã với suy nghĩ rằng người tiếp theo đọc mã của bạn là một kẻ rìu cầm rìu nối tiếp và anh ta ghét không thể hiểu được mã.
MattE

Xin chào Matt ... Tôi đang trình bày nó ở đây như một bằng chứng về khái niệm ... dù sao thì hình thức này cung cấp cho bạn tính linh hoạt và linh hoạt hơn ... và bạn chỉ sử dụng nó nếu bạn muốn ... hoặc nếu bạn tìm thấy một ràng buộc trong hình thức làm việc thông thường ... coi ir như một công cụ nữa trong hộp công cụ lập trình viên của bạn ...
ZEE

5

Tôi sử dụng như thế này:

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

Bạn không cần sử dụng gcờ, vì bạn chỉ sử dụng các biểu thức một lần và ném chúng đi. Trong thực tế, nếu bạn giữ chúng bên ngoài chức năng, gcờ sẽ gây hại cho bạn bằng cách cố gắng khớp với chỉ số khác 0 trên các .test(s tiếp theo . Tôi cũng đã sửa một lỗi đánh máy trong đó trường hợp chuyển đổi là sensorbiến và không phải là truehằng số để khớp với các biểu thức boolean. Xem chỉnh sửa.
Mihail Malostanidis

Tôi đã sử dụng định dạng này để kiểm tra các loại tập tin. Vd:case /officedocument/.test(type) && /presentation/.test(type): iconClass = "far fa-file-powerpoint red"; break;
tbone849

4

Nó phụ thuộc. Switch đánh giá một lần và chỉ một lần. Trong một trận đấu, tất cả các tuyên bố trường hợp tiếp theo cho đến khi 'phá vỡ' bất kể trường hợp nào nói.

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

Tôi thích điều này cho rõ ràng và cú pháp DRY.

varName = "larry";

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

    default: 
       alert('Default case');

}

2

Tôi có thể thấy có rất nhiều câu trả lời hay ở đây, nhưng điều gì xảy ra nếu chúng ta cần kiểm tra hơn 10 trường hợp? Đây là cách tiếp cận của riêng tôi:

 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
Đây là lạm dụng tuyên bố chuyển đổi. Chỉ if (accessDenied.includes(varName)) return 'Access Denied!'; return 'Access Allowed.'là quá đủ.
Mihail Malostanidis

2

Vấn đề với các cách tiếp cận ở trên, là bạn phải lặp lại vài casegiây mỗi khi bạn gọi hàm có switch. Một giải pháp mạnh mẽ hơn là có một bản đồ hoặc một cuốn từ điển .

Dưới đây là một ví dụ

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

Bạn có thể làm được việc này:

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

hoặc chỉ một dòng mã:

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

một chút cải thiện từ câu trả lời của ErikE


1

Đối với bất kỳ ai đến đây với một vấn đề tương tự mà tôi gặp phải, mà tôi đã gặp phải sau nhiều tuần viết mã và kiệt sức, tình huống của tôi giống như:

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

Luôn luôn là defaulttrường hợp nhập. Nếu bạn đang gặp vấn đề về câu lệnh chuyển đổi nhiều trường hợp tương tự, điều bạn đang tìm kiếm là:

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

Hy vọng điều này sẽ giúp được ai đó, tôi đã hất tóc ra trước khi nhớ sử dụng hộp chuyển đổi giống như cách tôi sử dụng nó trong các bộ giảm tốc.


0

Một trong những giải pháp khả thi là:

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

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

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

Q xin vui lòng #ecma này là gì?
BG Bruno

Chào bạn Đây là ES6
Jackkobec

0

Đối với tôi đây là cách đơn giản nhất:

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

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

-1

Một cách khác để thực hiện nhiều trường hợp trong câu lệnh switch, khi bên trong một hàm

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


-2

Bạn có thể viết nó như thế này:

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

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

6
Đây là câu trả lời giống như mọi người khác, tôi sẽ sửa lỗi "mà bạn đã quên, nhưng hãy nghĩ về việc xóa cái này.
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
bao gồm jquery cổ điển :)
ptim

4
Đây không phải là cách switchtuyên bố được cho là hoạt động. Chỉ là case "1":, không phải case (num = "1"):.
dùng4642212

Tại sao không đặt giá trị ngày bên trong trường hợp và document.getElementById("result").innerHTML = ....bên ngoài công tắc và thêm kết quả giá trị ngày vào cuối?
Steffo Dimfelt

@Xufox Tôi thích cách anh ấy ghi đè theo nghĩa đen numnhưng nó vẫn hoạt động vì switchđã được đánh giá và bài tập mang lại giá trị. Đây là lập trình bằng cách đột biến / học máy ở mức tốt nhất.
Mihail Malostanidis

-3

Chỉ cần chuyển đổi điều kiện chuyển đổi aprroach

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

2
Nếu bạn đặt đúng như biểu thức chuyển đổi, trong (các) câu lệnh "trường hợp", bạn có thể đánh giá bất cứ điều gì bạn muốn với điều kiện bạn trả lại một boolean
Stefano Favero

1
Tôi nghĩ điều anh ta muốn nói là bạn có thể đặt một biểu thức bên trong hàm, người sẽ đánh giá và trả về giá trị động cho trường hợp, do đó cho phép tất cả các loại điều kiện phức tạp
Z. Khullah 6/12/17

Đối với lưu ý @StefanoFavero này, bạn không thực sự cần một hàm, chỉ (expression)trong ngoặc đơn và giá trị trả về phải là đầu vào. Xem câu trả lời của tôi
Z. Khullah 6/12/17

tại sao bạn lại sử dụng nó ?? Tôi ủng hộ giải pháp này vì nó cung cấp sự linh hoạt cho các điều kiện phức tạp. Ngay cả khi bạn không thích funcs là điều kiện, bạn có thể thay thế chúng bằng nhiều điều kiện nhưswitch(true) { case (var1 === 0 && var2 === true): {} }
AlexNikonov
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.