ChatGPT解决这个技术问题 Extra ChatGPT

JavaScript中多个case的switch语句

我在 JavaScript 中的 switch 语句中需要多个案例,例如:

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

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

我怎样才能做到这一点?如果没有办法在 JavaScript 中做类似的事情,我想知道一个也遵循 DRY concept 的替代解决方案。

遗憾的是这种语法不起作用:(

u
user229044

使用 switch 语句的贯穿功能。匹配的案例将一直运行,直到找到 break(或 switch 语句的结尾),因此您可以将其编写为:

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

   default: 
       alert('Default case');
}

不知何故,它在 Chrome 中对我有用,在 javascript 控制台中:switch('10') { case 1, '10': console.log('ok') } 打印 ok
@nafg:试试 switch(1)。这里的标签只是一个逗号表达式。
@Barney 不,没有休息,您可以进入下一个案例。
@Seiyira 根据定义,最后一个案例之后没有下一个案例。此外,这是一个默认值。
P
Peter Mortensen

这适用于常规 JavaScript:

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

@believesInSanta 它实际上只是带有奇怪格式的正常情况(空格而不是换行符)
你也可以用 case (1||2||3): 代替 case 1: case 2: case 3:
案例1:案例2:案例3:为我工作,谢谢,但@kasun您的解决方案不起作用。
仅供参考,我在 TS 中尝试了@Kasun 的方法,但它对我不起作用(我知道 OP 想要 JS 中的解决方案)
@KasunHasanga 建议的解决方案不起作用的原因是因为 case (1||2||3): 等同于 case 1:(因为 1||2||3 评估为 1)。
e
elclanrs

这是完全避免 switch 语句的不同方法:

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

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

我绝对更喜欢这个版本。失败是 switch ... case 的一个容易出错的功能。忘记 break 语句太容易了,如果您有意使用 fall through,那些忘记的 break 语句可能很难被发现。这个方法查找版本还有很多switch ... case所缺乏的强大功能,比如动态扩展性,或者完全替换对象来完成模式切换的能力。它也更容易保持整洁,并且可以导致更可维护的代码。请参阅ericleads.com/2012/12/switch-case-considered-harmful
每当我有意省略 break 时,我总是添加注释 //fallthrough 来代替 break。这有助于识别何时是错误以及何时是故意的。
直观的方法。但是,为了可读性,我建议使用本机 switch 语句。
一个人总是可以通过右手从脖子后面刮伤左耳......(对不起我的英语,我的意思是:“一个人总是可以尽可能地使事情复杂化......在这种情况下,避免使用 switch 语句支持这种复杂的解决方案似乎不是正确的做法......)
我真的很惊讶这如何获得 34 票。就可读性和可维护性而言,这绝对是可怕的。如果我想看看什么条件会触发某些事情,那么通过查看标签,case 语句非常简单且易于查看。另一方面,您的版本需要有人阅读几乎每一行并查看您在哪里分配的内容。您想要匹配的案例越多,这也会变得更糟。
G
Geo

在 Javascript 中,要在一个 switch 中分配多个 case,我们必须定义 different case without break inbetween,如下所示:

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

请参阅点击 link 的示例


这是多种语言中的常用技术,不受 JS 约束
P
Peter Mortensen

为了清晰起见,我喜欢这个 DRY 语法。

varName = "larry";

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

    default:
       alert('Default case');

}

E
ErikE

如果你使用 ES6,你可以这样做:

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

或者对于早期版本的 JavaScript,您可以这样做:

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

请注意,includes 在某些浏览器(包括较旧的 IE 版本)中不起作用,但您可以相当轻松地进行修补。有关详细信息,请参阅问题 determine if string is in list in javascript


与交换机相比,这有什么好处?
@BryceSnyder 表达式和语句之间的区别?少打字?消耗的垂直线更少?通过简洁和密集的表现来增强表现力?通过 includes 词获得更好的语义?任你选。
对我来说的好处是,我可以使用来自外部配置源的数组,并且在外部更改数组后,代码仍然有效。
这是我的首选选项,这些案例选项块看起来很疯狂,包括可以使用原始数组而不是单独提取元素。
这是一个相当可靠的选项,唯一的缺点是它不像 switch 语句那样可读。
P
Peter Mortensen

我的情况类似于:

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

default 案例总是输入。如果您遇到类似的多案例 switch 语句问题,您正在寻找这个:

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

P
Peter Mortensen

添加并澄清Stefano's answer,您可以使用表达式动态设置switch中条件的值,例如:

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

    case 6: console.log('6');
}

因此,在您的问题中,您可以执行以下操作:

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

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

虽然是这么多DRY...


尚未测试,但在 case 表达式中修改 varName 会很有趣,希望您缓存 varName。
P
Peter Mortensen

在 Node.js 中,您似乎可以这样做:

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

在某些情况下,这使得代码更加紧凑。


我认为语法与其他 JS 环境相同。
@AfshinMehrabani 可能是,我只在 nodejs 上下文中测试过它。
是的。我喜欢节省垂直空间!
P
Peter Mortensen

我这样使用它:

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

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

您不需要使用 g 标志,因为您只使用了一次正则表达式并将它们丢弃。事实上,如果您将它们保留在函数之外,g 标志会通过尝试从后续 .test( 上的非 0 索引匹配来伤害您。我还修复了一个错字,其中 switch case 位于 sensor 变量而不是 true 常量以匹配布尔表达式。见编辑。
我使用这种格式来测试文件类型。例如:case /officedocument/.test(type) && /presentation/.test(type): iconClass = "far fa-file-powerpoint red"; break;
这可能是检查输入的最佳方法。有关建议的编辑,请参阅下一条评论。
R
Ronnie Royston

视情况而定。 Switch 评估一次且仅一次。在匹配时,无论 case 说什么,直到“break”的所有后续 case 语句都会触发。

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; 默认值: console.log('default'); } })(); // 返回 onlymen onlywomen onlyadults


从历史上看,switch 是(不)著名的 goto 语句的变体。这个想法是你去这些标签之一,然后继续。也就是说,标签代表入口点;如果您想退出,您必须自己完成,使用 break 语句,或者如果您在函数内部,则可能使用 return 语句。
P
Peter Mortensen

您可以使用“in”运算符...它依赖于对象/哈希调用,因此它与 JavaScript 一样快。

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

这与开关有什么关系?你能澄清一下吗?
你为什么要让你的代码“难以阅读”。作为一名程序员,我被告知的第一件事是编写代码时的心态是,下一个阅读您的代码的人是一个挥舞着斧头的连环杀手,他讨厌无法理解代码。
嗨,马特...我在这里展示它作为概念证明...无论如何,这种形式为您提供了更多的功能和灵活性...并且您只有在需要时才使用它...或者如果您在您的通常的做事形式......将ir视为程序员工具箱中的另一种工具......
S
Scott O'Dea

一些有趣的方法。对我来说,最好的解决方法是使用 .find

您可以通过在 find 函数中使用合适的名称来指示多种情况。

switch (varName)
{
   case ["afshin", "saeed", "larry"].find(firstName => firstName === varName):
       alert('Hey');
       break;

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

其他答案更适合给定的示例,但是如果您对我有多种情况,这是最好的方法。


我喜欢这种方法。它还可以很好地与 ESlint 和其他代码格式化程序一起使用
D
Dedy Abdillah

你可以这样做:

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

或者只是一行代码:

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

埃里克的回答有一点改进


P
Peter Mortensen

我可以看到这里有很多很好的答案,但是如果我们需要检查超过 10 个案例会发生什么?这是我自己的方法:

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

这是对 switch 语句的滥用。只需 if (accessDenied.includes(varName)) return 'Access Denied!'; return 'Access Allowed.' 就足够了。
P
Peter Mortensen

上述方法的问题在于,每次调用具有 switch 的函数时,您都必须重复几个 case。一个更强大的解决方案是有一个地图或一个字典

这是一个例子:

// 地图,除以概念 var dictionary = { timePeriod: { 'month': [1, 'monthly', 'mensal', 'mês'], 'twoMonths': [2, 'two months', '2 months ', 'bimestral', 'bimestre'], 'trimester': [3, 'trimesterly', ' Quarterly', 'trimestral'], 'semester': [4, 'semesterly', 'semestral', 'halfyearly'] , 'year': [5, 'yearly', 'annual', 'ano'] }, distance: { 'km': [1, 'kms', 'kilometre', 'kilometers', 'kilometres'], '英里':[2,'mi','miles'],'nordicMile':[3,'北欧英里','mil(10公里)','斯堪的纳维亚英里']},fuelAmount:{'ltr':[ 1, 'l', 'litre', 'Litre', 'liter', 'Liter'], 'gal (imp)': [2, 'imp gal', 'imperial gal', 'gal (UK)'] , 'gal (US)': [3, 'US gal', 'US gal'], 'kWh': [4, 'KWH'] } }; // 这个函数将每个输入映射到某个定义的值 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+'"') } // 你可以像这样使用它 mapUnit("fuelAmount", " ltr") // => ltr mapUnit("fuelAmount", "US gal") // => gal (US) mapUnit("fuelAmount", 3) // => gal (US) mapUnit("distance", " kmetre") // => km // 现在您可以安全地使用 switch 语句,而无需在每次调用 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': 控制台。 log('semester') break case 'year': console.log('year') break default: throw Error('error') }


J
Jackkobec

一种可能的解决方案是:

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

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

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

问 请问这是哪个#ecma?
你好呀。这是 ES6
P
Peter Mortensen

在函数内部时,在 switch 语句中执行多个案例的另一种方法:

函数名(varName){ switch(varName){ case 'afshin': case 'saeed': case 'larry': return 'Hey';默认值:返回“默认情况”; } } console.log(name('afshin')); // 嘿


A
Abraham

更清洁的处理方式

if (["triangle", "circle", "rectangle"].indexOf(base.type) > -1)
{
    //Do something
}else if (["areaMap", "irregular", "oval"].indexOf(base.type) > -1)
{
    //Do another thing
}

您可以对具有相同结果的多个值执行此操作


P
Peter Mortensen

只需更改开关条件方法:

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

如果您将 true 作为 switch 表达式,则在“case”语句中,您可以评估您想要的任何内容,只要您返回一个布尔值
我认为他的意思是你可以在函数中放置一个表达式,他将评估并返回一个动态值,从而允许各种复杂的条件
对于此@StefanoFavero 注意,您实际上不需要函数,只需 (expression) 在括号中,并且返回值必须是输入。看我的回答
为什么你减去它?我提倡这种解决方案,因为它为复杂条件提供了灵活性。即使您不喜欢 func 作为条件,也可以将它们替换为多个条件,例如 switch(true) { case (var1 === 0 && var2 === true): {} }
K
Kirandeep Singh
<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>

经典的jQuery包含:)
这不是 switch 语句的工作方式。它只是 case "1":,而不是 case (num = "1"):
为什么不将日值放在 case 内,document.getElementById("result").innerHTML = ....在 switch 外,然后在最后添加日值结果?
@Xufox 我喜欢他如何从字面上覆盖 num 但它仍然有效,因为 switch 已经被评估并且赋值产生了值。这是最好的变异/机器学习编程。
F
Felipe Skinner

你可以这样写:

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

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

这是和其他人一样的答案,我会修复你忘记的“,但考虑删除它。
P
Peter Mortensen

对我来说这是最简单的方法:

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

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

这是“最简单”的方法吗?只需将其替换为 if 语句即可。
如果数组中有 20 个元素,则需要 20 个 if。这种方式适用于许多元素。
一点也不.. 看,您的数组中已经有 3 个元素。您所需要的只是用额外的值填充该数组。塞巴斯蒂安在这里说的是,您的 switch 行为与 if 语句完全一样,所以您完全错了,而且您甚至没有考虑案例“2”,您只是假设默认值是您的“else”。