在 JavaScript 中打开整数范围

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5619832/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 18:05:03  来源:igfitidea点击:

Switch on ranges of integers in JavaScript

javascriptswitch-statement

提问by Jaanus

I want to do something like this

我想做这样的事情

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

What is the right syntax for this? Is it possible in JavaScript?

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

So this.dealeris an integer, and if it's between those values, do something.

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

回答by Alejandro Martin

Here is another way I figured it out:

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

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

回答by David Mason

Incrementing on the answer by MarvinLabs to make it cleaner:

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

It is not necessary to check the lower end of the range because the breakstatements will cause execution to skip remaining cases, so by the time execution gets to checking e.g. (x < 9) we know the value must be 5 or greater.

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

Of course the output is only correct if the cases stay in the original order, and we assume integer values (as stated in the question) - technically the ranges are between 5 and 8.999999999999 or so since all numbers in js are actually double-precision floating point numbers.

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

If you want to be able to move the cases around, or find it more readable to have the full range visible in each case statement, just add a less-than-or-equal check for the lower range of each 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;
}

Keep in mind that this adds an extra point of human error - someone may try to update a range, but forget to change it in both places, leaving an overlap or gap that is not covered. e.g. here the case of 8 will now not match anything when I just edit the case that used to match 8.

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

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

回答by Vincent Mimoun-Prat

    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 you don't like the succession of cases, simply go for if/else if/elsestatements.

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

回答by xtempore

This does not require a switch statement. It is clearer, more concise, faster, and optimises better, to use if else statements...

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

Speed test

速度测试

I was curious about the overhead of using a switch instead of the simpler if...else..., so I put together a jsFiddle to examine it... http://jsfiddle.net/17x9w1eL/

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

  • Chrome: switchwas around 70% slower than if else

  • Firefox: switchwas around 5% slower than if else

  • IE: switchwas around 5% slower than if else

  • Safari: switchwas around 95% slower than if else

  • Chrome:switchif else慢 70% 左右

  • Firefox:switchif else慢 5% 左右

  • IE: switchif else慢 5% 左右

  • Safari: switchif else慢 95%

Notes:

笔记:

Assigning to the local variable is optional, especially if your code is going to be automatically optimised later.

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

For numeric ranges, I like to use this kind of construction...

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

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

... because to me it reads closer to the way you would express a range in maths (1 <= d <= 11), and when I'm reading the code, I can read that as "if d is between 1 and 11".

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

Clearer

更清晰

A few people don't think this is clearer. I'd say it is not less clear as the structure is close to identical to the switch option. The main reason it is cleareris that every part of it is readable and makes simple intuitive sense.

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

My concern, with "switch (true)", is that it can appear to be a meaningless line of code. Many coders, reading that will not know what to make of it.

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

For my own code, I'm more willing to use obscure structures from time to time, but if anyone else will look at it, I try to use clearer constructs. I think it is better to use the constructs for what they are intended.

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

Optimisation

优化

In a modern environment, code is often going to be minified for production, so you can write clear concise code, with readable variable names and helpful comments. There's no clear reason to use switch in this way.

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

I also tried putting both constructs through a minifier. The if/else structure compresses well, becoming a single short expression using nested ternary operators. The switch statement when minified remains a switch, complete with "switch", "case" and "break" tokens, and as a result is considerably longer in code.

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

How switch(true) works

switch(true) 如何工作

I think "switch(true) is obscure, but it seems some people just want to use it, so here's an explanation of why it works...

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

A switch/case statement works by matching the part in the switch with each case, and then executing the code on the first match. In most use cases, we have a variable or non-constant expression in the switch, and then match it.

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

With "switch(true), we will find the first expression in the case statements that is true. If you read "switch (true)" as "find the first expression that is true", the code feels more readable.

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

回答by Kevin

If you need check ranges you are probably better off with ifand else ifstatements, like so:

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

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

A switch could get large on bigger ranges.

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

回答by RoToRa

No, this is not possible. The closest you can get is:

不,这是不可能的。你能得到的最接近的是:

  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;

But this very unwieldly.

但这非常笨拙。

For cases like this it's usually better just to use a if/else ifstructure.

对于这种情况,通常最好使用if/else if结构。

回答by Brook Jordan

A more readable version of the ternary might look like:

更具可读性的三元版本可能如下所示:

var x = this.dealer;
alert(t < 1 || t > 11
  ? 'none'
    : t < 5
  ? 'less than five'
    : t <= 8
  ? 'between 5 and 8'
  : 'Between 9 and 11');

回答by Shalto

function sequentialSizes(val) {
 var answer = "";

 switch (val){
case 1:
case 2:
case 3:
case 4:
  answer="Less than five";
  break;
case 5:
case 6:
case 7:
case 8:
  answer="less than 9";
  break;
case 8:
case 10:
case 11:
  answer="More than 10";
  break;
 }

return answer;  
}

// Change this value to test you code to confirm ;)
sequentialSizes(1);

回答by John Pace

If you are trying to do something fast, efficient and readable, use a standard if...then...else structure like this:

如果您正在尝试做一些快速、高效和可读的事情,请使用标准的 if...then...else 结构,如下所示:

var d = this.dealer;
if (d < 12) {
    if (d < 5) {
        alert("less than five");
    }else if (d < 9) {
        alert("between 5 and 8");
    }else{
        alert("between 9 and 11");
    }
}else{
    alert("none");
}

If you want to obfuscate it and make it awful (but small), try this:

如果你想混淆它并让它变得糟糕(但很小),试试这个:

var d=this.dealer;d<12?(d<5?alert("less than five"):d<9?alert("between 5 and 8"):alert("between 9 and 11")):alert("none");

BTW, the above code is a JavaScript if...then...else shorthand statement. It is a great example of how NOT to write code unless obfuscation or code minification is the goal. Be aware that code maintenance can be an issue if written this way. Very few people can easily read through it, if at all. The code size, however, is 50% smaller than the standard if...then...else without any loss of performance. This means that in larger codebases, minification like this can greatly speed code delivery across bandwidth constrained or high latency networks.

顺便说一句,上面的代码是一个 JavaScript if...then...else 速记语句。这是一个很好的例子,说明除非混淆或代码缩小是目标,否则如何不编写代码。请注意,如果以这种方式编写,代码维护可能是一个问题。很少有人可以轻松通读它,如果有的话。然而,代码大小比标准小 50% if...then...else 没有任何性能损失。这意味着在更大的代码库中,像这样的缩小可以极大地加快跨带宽受限或高延迟网络的代码交付。

This, however, should not be considered a good answer. It is just an example of what CAN be done, not what SHOULD be done.

然而,这不应被视为一个好的答案。这只是可以做什么的一个例子,而不是应该做什么。