在 JavaScript 中打开整数范围

IT技术 javascript switch-statement
2021-02-10 05:43:03

我想做这样的事情

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

什么是正确的语法?在 JavaScript 中可能吗?

this.dealer整数也是如此,如果它介于这些值之间,请执行某些操作。

6个回答

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

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;
}
@Alejandro Martin:Switch 语句很有用,因为它们提供了更简洁、更易读的代码。您的示例需要的行数比必要的多,并且代码远不如等效的 if-then-else 结构清晰。这只是工作的正确结构的一个例子。仅仅因为您能够使用 switch 语句创建晦涩的次优代码并不能提供从所有语言中删除 switch 语句的理由。
2021-03-15 05:43:03
当然,这是一个巧妙的技巧,但在这一点上,仅使用一串 if else if 语句有什么好处?
2021-03-27 05:43:03
这可以通过删除每个 > 比较来显着改善,它们只会让它变得混乱。在第二种情况下,我们知道 x 不能小于 5,所以我们不妨不包括重叠的比较 - 它们只会在以后引起混淆。
2021-04-05 05:43:03
@Superman 你说得很好。我认为每个人都应该记住代码是我们所谈论的,而不是人,这一点很重要。如果有人指出我编写的某些代码存在问题,我会学习一些东西,并在下次编写更好的代码。我个人承受不起:我不是代码,代码不是我或我的宝贝。如果我试图为我的所有代码辩护不受任何批评,我将永远无法改正我所有的坏习惯或学习任何新东西。
2021-04-05 05:43:03
@xtempore 我从这个答案中受益,并在我丑陋的代码中使用只是为了让事情正常工作。是的,我同意我想要一些更优化和整洁的东西,它可以很好地与我正在编写的软件配合使用。但事实是,像我这样的人来这里是为了解决问题,并记住每个初学者如果继续滚动就达到了顶峰,并且无论好坏都不要停在这一点上。他/她把事情做好真的很重要。他们在一段时间内学习,这需要时间。
2021-04-09 05:43:03

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

没有必要检查范围的下限,因为这些break语句会导致执行跳过剩余的情况,因此当执行开始检查 (x < 9) 时,我们知道该值必须是 5 或更大。

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

如果您希望能够移动案例,或者发现在每个 case 语句中显示完整范围更具可读性,只需为每个案例的较低范围添加小于或等于检查:

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

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

    case (x >= 5 && x < 8):
        alert("between 5 and 7");
        break;
    case (x >= 9 && x < 12):
        alert("between 9 and 11");
        break;
恕我直言,这是非常糟糕的风格 - switch 语句的正确性现在取决于案例的顺序。这会损害可读性和可维护性,特别是对于不再适合当前编辑器视口的 case 语句(尽管有些人认为无论如何要避免像这样的冗长结构),并且 afaik 实际上可能会阻碍优化(您不能再根据减少的顺序对 case 进行排序)运行时发生的频率)。
2021-03-21 05:43:03
不过,@collapsar 可读性问题值得考虑,如果您可以始终如一地使用 switch 语句,使每种情况都是互斥的(因此本质上好像它是一组 if-then-else 语句的较短语法),我可以看到有益于认知负荷。然后添加将是>=为每个案例添加对较低范围检查。如果您关心过早的性能微优化,请记住这是解释器要处理的一项额外的数字比较。
2021-04-05 05:43:03
JavaScript 中的 @collapsar case 语句基本上是依赖于顺序的。盲目地重新排序案例是不明智的。您所谈论的优化仅在某些非常有限的情况下相关-大多数程序永远不会从此类优化中获得任何好处,因此我认为编写代码来迎合它们没有任何value-这种情况很少见优化需要多做一点工作,但区别很小。
2021-04-07 05:43:03
    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;
    }

如果您不喜欢连续的案例,只需选择if/else if/else陈述即可。

这适用于小范围,在我的情况下,范围更大(> = 100)这将是一场噩梦
2021-04-04 05:43:03
这是一个更好的解决方案imo,因为它实际上展示了发明开关的原因之一。
2021-04-08 05:43:03

不需要 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");
}

速度测试

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

  • Chrome:switchif else慢 70% 左右

  • Firefox:switchif else慢 5% 左右

  • IE: switchif else慢 5% 左右

  • Safari: switchif else慢了大约 95%

笔记:

分配给局部变量是可选的,尤其是当您的代码稍后要自动优化时。

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

if (1 <= d && d <= 11) {...}

...因为对我来说它更接近于你在数学中表达范围的方式 (1 <= d <= 11),当我阅读代码时,我可以将其读作“如果 d 介于 1 和11"。

更清晰

一些人认为这不是更清楚。我想说它并不太清楚,因为结构与 switch 选项几乎相同。更清晰的主要原因是它的每个部分都是可读的并且具有简单的直观意义。

我对“switch (true)”的担忧是,它可能看起来是一行毫无意义的代码。许多编码员,阅读这些内容时不知道该怎么做。

对于我自己的代码,我更愿意不时使用晦涩的结构,但如果其他人会看它,我会尝试使用更清晰的结构。我认为最好将这些结构用于它们的目的。

优化

在现代环境中,代码通常会被缩小以用于生产,因此您可以编写清晰简洁的代码,具有可读的变量名称和有用的注释。没有明确的理由以这种方式使用 switch。

我还尝试将这两种构造都通过一个压缩器。if/else 结构压缩得很好,成为使用嵌套三元运算符的单个短表达式。缩小后的 switch 语句仍然是一个 switch,带有“switch”、“case”和“break”标记,因此代码要长得多。

switch(true) 如何工作

我认为“switch(true) 很模糊,但似乎有些人只是想使用它,所以这里解释一下它为什么起作用......

switch/case 语句的工作原理是将 switch 中的部分与每个 case 进行匹配,然后在第一个匹配项上执行代码。在大多数用例中,我们在 switch 中有一个变量或非常量表达式,然后匹配它。

用“switch(true)”,我们会找到case语句中第一个为真的表达式。如果把“switch(true)”读成“找到第一个为真的表达式”,代码感觉更可读。

不太清楚imo
2021-03-15 05:43:03
ymmv - 事实上,说得很清楚,我觉得这段代码比搜索的 switch 语句更难阅读。速度测试并不能说服我 - 该语句将是代码库的一小段。是否值得优化,只有分析或仔细的上下文分析才能说明问题,如果是,您通常可以通过降低运行时发生频率对案例进行排序来获得更多收益。(此评论并不是要将您的方法标记为低劣;如前所述,ymmv,当然,所有声明都只是恕我直言;-)),
2021-03-16 05:43:03
你不是在回答这个问题。op打算使用switch
2021-03-21 05:43:03
只是把我的 2 美分扔在那里......我倾向于发现在 switch 语句和级联 if/else 语句之间进行选择(不包括对 switch(true) 的担忧)归结为两件事:1)有多少种情况?任何超过 5 我发现开关更容易阅读。2) 我返回并添加其他案例的可能性有多大?添加另一个案例比添加另一个 else if 块更快(或者至少在尝试将修补程序用于生产时感觉是这样)
2021-03-22 05:43:03
不同意,使用起来更清楚 switch
2021-04-03 05:43:03

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

if (range > 0 && range < 5)
{
    // ..
}
else if (range > 5 && range < 9)
{
    // ..
}
else
{
    // Fall through
}

在更大的范围内,开关可能会变大。

能变“大”吗?
2021-03-26 05:43:03