如何在使用 JavaScript 的 switch case 语句中使用范围?

2022-01-19 00:00:00 intervals switch-statement javascript

如何在使用 JavaScript 的 switch case 语句中使用范围?因此,我不想为每一种可能性编写代码,而是将它们按范围分组,例如:

How can I use ranges in a switch case statement using JavaScript? So, instead of writing code for each and every single possibility, I'd like to group them in ranges, For example:

switch(myInterval){
   case 0-2:
      //doStuffWithFirstRange();
      break;

   case 3-6:
      //doStuffWithSecondRange();
      break;

   case 6-7:
      //doStuffWithThirdRange();
      break;

   default:
      //doStuffWithAllOthers();
}

推荐答案

你至少有四个选择:

如 LightStyle 所示,您可以明确列出每个案例:

As shown by LightStyle, you can list each case explicitly:

switch(myInterval){

    case 0:
    case 1:
    case 2:
        doStuffWithFirstRange();
        break;

    case 3:
    case 4:
    case 5:
        doStuffWithSecondRange();
        break;

    case 6:
    case 7:
        doStuffWithThirdRange();
        break;

    default:
        doStuffWithAllOthers();
}

2.使用 if/else if/else

如果范围很大,那会变得笨拙,所以你会想要做范围.请注意,使用 if...else if...else if,如果较早的匹配,则不会到达后面的,因此您每次只需指定上限.为了清楚起见,我将在 /*...*/ 中包含下限,但通常您会保留它以避免引入维护问题(如果您包含两个边界,则很容易更改一个而忘记改变另一个):

2. Use if / else if / else

If the ranges are large, that gets unwieldy, so you'd want to do ranges. Note that with if...else if...else if, you don't get to the later ones if an earlier one matches, so you only have to specify the upper bound each time. I'll include the lower bound in /*...*/ for clarity, but normally you would leave it off to avoid introducing a maintenance issue (if you include both boundaries, it's easy to change one and forget to change the other):

if (myInterval < 0) {
    // I'm guessing this is an error
}
else if (/* myInterval >= 0 && */ myInterval <= 2){
    doStuffWithFirstRange();
}
else if (/* myInterval >= 3 && */ myInterval <= 5) {
    doStuffWithSecondRange();
}
else if (/* myInterval >= 6 && */ myInterval <= 7) {
    doStuffWithThirdRange();
}
else {
    doStuffWithAllOthers();
}

3.将 case 与表达式一起使用:

JavaScript 的不寻常之处在于您可以在 case 语句中使用表达式,因此我们可以将上面的 if...else if...else if 序列写为switch 语句:

3. Use case with expressions:

JavaScript is unusual in that you can use expressions in the case statement, so we can write the if...else if...else if sequence above as a switch statement:

switch (true){

    case myInterval < 0:
        // I'm guessing this is an error
        break;    
    case /* myInterval >= 0 && */ myInterval <= 2:
        doStuffWithFirstRange();
        break;

    case /* myInterval >= 3 && */ myInterval <= 5:
        doStuffWithSecondRange();
        break;

    case /* myInterval >= 6 && */ myInterval <= 7:
        doStuffWithThirdRange();
        break;

    default:
        doStuffWithAllOthers();
}

我不提倡这样做,但它是 JavaScript 中的一个选项,而且有时它很有用.case 语句会根据您在 switch 中给出的值按顺序进行检查.(同样,在许多情况下可以省略下限,因为它们会更早匹配.) 即使 case 是按源代码顺序处理的,default 可以出现在任何地方(不仅仅是在末尾),并且仅在没有匹配的 case 或匹配的 case 并通过默认值时才被处理(没有break;你很少想这样做,但它确实发生了).

I'm not advocating that, but it is an option in JavaScript, and there are times it's useful. The case statements are checked in order against the value you give in the switch. (And again, lower bounds could be omitted in many cases because they would have matched earlier.) Even though the cases are processed in source-code order, the default can appear anywhere (not just at the end) and is only processed if either no cases matched or a case matched and fell through to the default (didn't have a break; it's rare you want to do that, but it happens).

如果您的函数都采用相同的参数(可能没有参数,或者只是相同的参数),另一种方法是调度映射:

If your functions all take the same arguments (and that could be no arguments, or just the same ones), another approach is a dispatch map:

在一些设置代码中:

var dispatcher = {
    0: doStuffWithFirstRange,
    1: doStuffWithFirstRange,
    2: doStuffWithFirstRange,

    3: doStuffWithSecondRange,
    4: doStuffWithSecondRange,
    5: doStuffWithSecondRange,

    6: doStuffWithThirdRange,
    7: doStuffWithThirdRange
};

然后代替开关:

(dispatcher[myInterval] || doStuffWithAllOthers)();

通过在 dispatcher 映射上查找要调用的函数来工作,如果该特定 myInterval 值没有条目,则默认为 doStuffWithAllOthers使用 功能强大的 || 运算符,然后调用它.

That works by looking up the function to call on the dispatcher map, defaulting to doStuffWithAllOthers if there's no entry for that specific myInterval value using the curiously-powerful || operator, and then calling it.

您可以将其分成两行以使其更清晰:

You can break that into two lines to make it a bit clearer:

var f = dispatcher[myInterval] || doStuffWithAllOthers;
f();

我使用了一个对象以获得最大的灵活性.您可以在您的具体示例中像这样定义 dispatcher:

I've used an object for maximum flexibility. You could define dispatcher like this with your specific example:

var dispatcher = [
    /* 0-2 */
    doStuffWithFirstRange,
    doStuffWithFirstRange,
    doStuffWithFirstRange,

    /* 3-5 */
    doStuffWithSecondRange,
    doStuffWithSecondRange,
    doStuffWithSecondRange,

    /* 6-7 */
    doStuffWithThirdRange,
    doStuffWithThirdRange
];

...但是如果值不是连续的数字,那么使用对象会更清楚.

...but if the values aren't contiguous numbers, it's much clearer to use an object instead.

相关文章