在JavaScript中切换整数范围

Jaa*_*nus 125 javascript switch-statement

我想做这样的事情

    switch (this.dealer) {
        case 1-4: 
            // Do something.
            break;
        case 5-8: 
            // Do something.
            break;
        case 9-11: 
            // Do something.
            break;
        default:
            break;
    }
Run Code Online (Sandbox Code Playgroud)

这个的正确语法是什么?在JavaScript中可以吗?

那么this.dealer是一个整数,如果它在这些值之间,那么就做一些事情.

Ale*_*tin 259

这是我想出来的另一种方式:

const x = this.dealer;
switch (true) {
    case (x < 5):
        alert("less than five");
        break;
    case (x < 9):
        alert("between 5 and 8");
        break;
    case (x < 12):
        alert("between 9 and 11");
        break;
    default:
        alert("none");
        break;
}
Run Code Online (Sandbox Code Playgroud)

  • 当然,这是一个巧妙的伎俩,但在那一点上,只有if if if语句链的好处是什么呢? (21认同)
  • 通过删除每个>比较可以显着改善这一点,它们只是让它变得混乱.在第二种情况下,我们知道x必须不小于5,所以我们不应该包括重叠的比较 - 它们将在稍后引起混淆. (21认同)
  • @Alejandro Martin:Switch语句非常有用,因为它们提供的代码更简洁,更易读.您的示例需要的行数多于必要的行数,并且代码远不及等效的if-then-else结构.这只是一个正确的工作结构的案例.仅仅因为您能够使用switch语句创建模糊的次优代码并不能提供从所有语言中删除switch语句的基本原理. (6认同)
  • 整洁的技巧,谢谢 (4认同)
  • @Superman你提出了一个很好的观点.我认为每个人都必须记住代码是我们所谈论的,而不是人.如果有人指出我写的一些代码有问题,我会学习一些东西并在下次编写更好的代码.我不能亲自接受:我不是代码,代码不是我或我的宝贝.如果我试图保护我的所有代码免受任何批评,我将永远不会修复我的所有坏习惯或学习任何新的东西. (3认同)
  • @xtempore :也许你不太清楚,也许对于提出问题的人来说,if else 语句链更难阅读。这是主观的。对我来说,这真的无关紧要,我从来不需要以这种方式在 javascript 中使用开关。但是其他人可能会发现这种技术很有用。无论如何,我认为您没有抓住问题的重点。有人问是否有可能在 javascript 中使用 int 范围进行切换,答案表明这是可能的。时期。 (2认同)
  • @xtempore我从这个答案中受益,并在我丑陋的代码中使用,只是为了让事情有效.是的我同意我想要一些更优化和整洁的东西,它与我正在编写的软件很好地配合.但事实是,像我这样的人来到这里是为了解决问题,并记住每个初学者如果继续滚动并且不停止在这一点上是否更好或更糟.他/她完成任务真的很重要.他们在一段时间内学习需要时间. (2认同)
  • 我个人认为当时有更多的选民失败,那么那些真正希望解决他人问题并愿意回答他们以帮助他们的人.我来这里是为了欣赏他们.而不是在这里批评另一组人.因为他们必须学习什么是必需的东西?一旦他们愿意,他们会没事的.:) (2认同)
  • @xtempore你们两个都是对的,而且你们两个都知识渊博,现在就是因为这次谈话你们彼此都不喜欢.我会建议你们互相微笑,不要说话.亚历杭德罗只是想帮助这个人.而你只是想告诉要学习的东西.这表明你们两个都很棒,你们两个都是社区的宝石.请原谅对方保持冷静,互相微笑.我们社区的初级和知识渊博的人都向你致敬.:) (2认同)

Dav*_*son 43

增加MarvinLabs的答案,使其更清洁:

var x = this.dealer;
switch (true) {
    case (x < 5):
        alert("less than five");
        break;
    case (x < 9):
        alert("between 5 and 8");
        break;
    case (x < 12):
        alert("between 9 and 11");
        break;
    default:
        alert("none");
        break;
}
Run Code Online (Sandbox Code Playgroud)

这是没有必要检查该范围的下端,因为break语句将导致执行跳过其余的情况下,使得由时间执行到达检查例如(X <9),我们知道其值必须为5或更大.

当然,如果情况保持原始顺序,输出只是正确的,我们假设整数值(如问题中所述) - 从技术上讲,范围介于5和8.999999999999左右,因为js中的所有数字实际上都是双精度浮点数点数.

如果您希望能够移动案例,或者发现它更具可读性以使每个案例语句中的全部范围可见,则只需为每个案例的较低范围添加一个小于或等于的检查:

var x = this.dealer;
switch (true) {
    case (x < 5):
        alert("less than five");
        break;
    case (x >= 5 && x < 9):
        alert("between 5 and 8");
        break;
    case (x >= 9 && x < 12):
        alert("between 9 and 11");
        break;
    default:
        alert("none");
        break;
}
Run Code Online (Sandbox Code Playgroud)

请记住,这会增加额外的人为错误点 - 有人可能会尝试更新范围,但忘记在两个地方更改它,留下未覆盖的重叠或间隙.例如,当我只编辑用于匹配8的情况时,8的情况现在将不匹配任何内容.

    case (x >= 5 && x < 8):
        alert("between 5 and 7");
        break;
    case (x >= 9 && x < 12):
        alert("between 9 and 11");
        break;
Run Code Online (Sandbox Code Playgroud)

  • JavaScript中的@collapsar case语句基本上依赖于顺序.永远盲目地重新安排案件是不明智的.你所谈论的那种优化只在一些非常有限的情况下才有意义 - 大多数程序都不会从这种优化中看到任何好处,所以我认为编写代码以满足它们没有任何价值 - 这种情况很少见优化需要更多的工作,但差异是微不足道的. (3认同)
  • Imho这是非常糟糕的样式 - switch语句的正确性现在取决于案例的顺序.这会损害可读性和可维护性,特别是对于不再适合当前编辑器视口的case语句(尽管有些人主张避免这样的冗长结构),并且afaik实际上可能会阻碍优化(你不能再根据减少的顺序来排序)运行频率(). (2认同)
  • @collapsar可读性问题值得考虑,如果你可以一直使用switch语句,使每个case都是互斥的(基本上就好像它是一组if-then-else语句的更短语法)我可以看到对认知负荷有益.然后添加一个`> =`检查每个案例的较低范围.如果您关心过早的性能微优化,请记住这是解释器要处理的额外数值比较. (2认同)

Vin*_*rat 20

    switch(this.dealer) {
        case 1:
        case 2:
        case 3:
        case 4:
            // Do something.
            break;
        case 5:
        case 6:
        case 7:
        case 8:
            // Do something.
            break;
        default:
            break;
    }
Run Code Online (Sandbox Code Playgroud)

如果你不喜欢连续的案例,那就干脆去做if/else if/else陈述.

  • 这是一个更好的解决方案,因为它实际上证明了开关的发明原因之一. (6认同)

xte*_*ore 14

并不需要一个switch语句.简单地使用if else语句会更清晰,更简洁,更快捷 ......

var d = this.dealer;
if (1 <= d && d <= 11) { // making sure in range 1..11
    if (d <= 4) {
        alert("1 to 4");
    } else if (d <= 8) {
        alert("5 to 8");
    } else {
        alert("9 to 11");
    }
} else {
    alert("not in range");
}
Run Code Online (Sandbox Code Playgroud)

速度测试

我很好奇使用开关的开销,而不是更简单的if ... else ...,所以我把一个jsFiddle放在一起检查它... http://jsfiddle.net/17x9w1eL/

  • Chrome:切换其他版本慢了约70%

  • Firefox:切换其他情况慢约5%

  • IE:开关其他情况慢了约5%

  • Safari:切换其他时间慢约95%

笔记:

分配给局部变量是可选的,特别是如果您的代码将在以后自动优化.

对于数值范围,我喜欢使用这种结构......

if (1 <= d && d <= 11) {...}
Run Code Online (Sandbox Code Playgroud)

...因为对我而言,它更接近你在数学中表达范围的方式(1 <= d <= 11),当我读代码时,我可以读到"如果d介于1和1之间11" .

更清晰

一些人评论说他们认为这不是更清楚.由于结构与开关选项接近相同,因此当然不会那么清楚.更清楚的主要原因是它的每个部分都是可读的并且简单直观,而"switch(true)"是一个相当无意义的代码行.许多程序员在你的剧本中读到这些内容,"WTF的意思是什么?" 然后必须查找它.这是一个肮脏的黑客,它不直观,而且还不清楚.如果这就是你喜欢编码的方式,而且没有其他人会不得不处理你的代码库,那就去吧,否则,最好只使用这些结构来实现它们的目的.

  • ymmv - 事实上,在清晰度方面,我觉得这个代码比搜索的switch语句更难阅读.速度测试并不能说服我 - 声明将是代码库的一小部分.无论是否值得优化,只有剖析或仔细的上下文分析才能说明,如果是,通常可以通过降低运行时间的频率来对案例进行排序,从而获得更多收益.(这个评论并不意味着将你的方法标记为劣等;如前所述,ymmv,当然,所有的声明只有imho ;-)), (4认同)
  • 没有更清楚的海事组织 (2认同)
  • 只是把我的 2 美分扔在那里......我倾向于发现在 switch 语句和级联 if/else 语句之间进行选择(不包括对 switch(true) 的关注)可以归结为两件事:1)有多少种情况?我发现超过 5 个开关更容易阅读。2) 我有多大可能返回并添加其他案例?添加另一个案例比添加另一个 else if 块更快(或者至少在尝试将修补程序投入生产时感觉是这样) (2认同)
  • 您没有回答问题。op打算使用`switch` (2认同)
  • 不同意,使用`switch`更清楚 (2认同)

Kev*_*vin 5

如果您需要检查范围,最好使用ifandelse if语句,如下所示:

if (range > 0 && range < 5)
{
    // ..
}
else if (range > 5 && range < 9)
{
    // ..
}
else
{
    // Fall through
}
Run Code Online (Sandbox Code Playgroud)

开关可以在更大的范围内变大。