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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17145723/
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-10-27 07:15:32  来源:igfitidea点击:

How can I use ranges in a switch case statement using JavaScript?

javascriptswitch-statementintervals

提问by Lave Loos

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:

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

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

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

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

   default:
      //doStuffWithAllOthers();
}

回答by T.J. Crowder

You have at least four options:

你至少有四个选择:

1. List each case

1. 列出每个 case

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

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

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. Use if/ else if/ else

2.使用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...else if...else if,如果较早的匹配,则无法访问较晚的,因此每次只需指定上限。/*...*/为清楚起见,我将包含下限,但通常您会忽略它以避免引入维护问题(如果您包含两个边界,则很容易更改一个而忘记更改另一个):

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. Use casewith expressions:

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

JavaScript is unusual in that you can use expressions in the casestatement, so we can write the if...else if...else ifsequence above as a switchstatement:

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

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

I'm not advocating that, but it isan option in JavaScript, and there are times it's useful. The casestatements are checked in orderagainst 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 defaultcan appear anywhere (not just at the end) and is only processed if either no cases matched or a casematched and fell through to the default (didn't have a break; it's rare you want to do that, but it happens).

我不提倡这样做,但它JavaScript 中的一个选项,有时它很有用。这些case语句按照您在switch. (同样,在许多情况下可以省略下界,因为它们会更早地匹配。)即使cases 是按源代码顺序处理的,它default也可以出现在任何地方(不仅仅是最后),并且只有在没有的情况下才会被处理cases 匹配或case匹配并落入默认值(没有break;您很少想这样做,但它发生了)。

4. Use a dispatch map

4. 使用调度图

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:

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

In some setup code:

在一些设置代码中:

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

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

    6: doStuffWithThirdRange,
    7: doStuffWithThirdRange
};

Then instead of the switch:

然后代替开关:

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

That works by looking up the function to call on the dispatchermap, defaulting to doStuffWithAllOthersif there's no entry for that specific myIntervalvalue using the curiously-powerful ||operator, and then calling it.

这是通过在dispatcher地图上查找要调用的函数来实现的,doStuffWithAllOthers如果myInterval使用功能强大的||运算符没有该特定值的条目,则默认为,然后调用它。

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

你可以把它分成两行,让它更清楚一点:

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

I've used an object for maximum flexibility. You coulddefine dispatcherlike this with your specific example:

我使用了一个对象以获得最大的灵活性。你可以dispatcher用你的具体例子这样定义:

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.

...但如果值不是连续的数字,则使用对象来代替会更清晰。

回答by twknab

The ranges in this example are pretty small, but here's how one can handle larger ranges, per the JavaScript MDN Docs:

这个例子中的范围非常小,但根据JavaScript MDN Docs,这里是如何处理更大的范围:

// The value we'll be evaluating:
let code = 100;

// Matches for any case where the expression === `true`:
switch (true) {
  case code <= 64:
    return "Your number is 64 or less!";
    break;
  case code >= 65 && code <= 90:
    return "Your number is in the range of 65-90!";
    break;
  case code >= 97 && code <= 122:
    return "Your number is in the range of 97-122!";
    break;
  case code >= 123:
    return "Your number is 123 or greater!";
    break;
  default:
    break;
}

I know that this style was already shown by T.J. Crowdervia Use casewith Expressions, but I just wanted to show another example of how to utilize this same method. I just did this and had thought maybe another example might help someone, as I was still a little confused after reading other replies.

我知道TJ Crowder已经通过Use casewith Expressions展示了这种风格,但我只是想展示另一个如何使用相同方法的示例。我只是这样做了,并认为也许另一个例子可以帮助某人,因为在阅读其他回复后我仍然有点困惑。

回答by Niccolò Campolungo

Is this maybe what you need?

这可能是你需要的吗?

switch(myInterval){

    case 0:
    case 1:
    case 2:
        //doStuff();
        break;

    case 3:
    case 4:
    case 5:
    case 6:
        //doStuff();
        break;

    case 6:
    case 7:
        //doStuff();
        break;

    default:
        //doStuff();
}

If you know the range is going to be very high(for example 0-100) you can also do this, which is surely easier, cleaner and simpler:

如果您知道范围将非常高(例如0-100),您也可以这样做,这肯定更容易,更干净,更简单:

if (myInterval >= 0 && myInterval <= 20) {
    //doStuff();
} else if (myInterval > 20 && myInterval <= 60) {
    //doStuff();
} else if (myInterval > 60 && myInterval <= 70) {
    //doStuff();
} else /* it is greater than 70 */ {
    //doStuff();
}

回答by iamdimitar

If your ranges are the same and start from 0 you can do some math.

如果您的范围相同并且从 0 开始,您可以做一些数学运算。

doStuffWithRange(Math.floor(myInterval/range));

For example, if you want RED, GREEN, and BLUE to the map like your example:

例如,如果您希望像您的示例一样在地图上显示红色、绿色和蓝色:

  • Range 0-2 maps to RED
  • Range 3-6 maps to GREEN
  • Range 7-8 maps to BLUE
  • 范围 0-2 映射到 RED
  • 范围 3-6 映射到绿色
  • 范围 7-8 映射到 BLUE

You can write:

你可以写:

function colorInterval(n, max) {
     var colors = ["RED", "GREEN", "BLUE"];
     var range = max/colors.length
     return colors[Math.floor(n/range)];
 }

//You get 3 of RED, 3 of GREEN, 2 of BLUE
for (var i=0; i<8; i++) {
    console.log(colorInterval(i, 8));
} 

Note that the last range in the example is 2, not 3 and this still works as long as the previous ranges are the same.

请注意,示例中的最后一个范围是 2,而不是 3,只要前面的范围相同,这仍然有效。

回答by Al-un

To add a bit of diversity to the excellent answers already posted, especially as the intervals starts with 0, here is a solution with findIndex(Yeah ES6):

为了给已经发布的优秀答案添加一点多样性,特别是当间隔从 0 开始时,这里有一个解决方案findIndex是的 ES6):

const range = [0, 2, 6, 7];
const randeIndex = range.findIndex(threshold => myInterval <= threshold);
switch (rangeIndex) {
  case 1:
    //doStuffWithFirstRange();
    break;

  case 2:
    //doStuffWithSecondRange();
    break;

  case 3:
    //doStuffWithThirdRange();
    break;
  default:
  //doStuffWithAllOthers();
}

Because the rangearray is ordered, findIndexwill match the first one. Depending on how you nameyour ranges, stating from 0 or 1, you may need to remove the first 0 in range.

因为range数组是有序的,findIndex会匹配第一个。根据您命名范围的方式,从 0 或 1 开始,您可能需要删除range.

回答by Sandip Patel - SM

int levelNumber = YOUR_VALUE FROM

int levelNumber = YOUR_VALUE FROM

NSString* strMessage;

switch (levelNumber) {
    case 1...10:
    {
        // Do something...
        break;
    }
    case 11...20:
    {
        // Do something...
        break;
    }
    case 21...30:
    {
        // Do something...
        break;
    }
    case 31...40:
    {
        // Do something...
        break;
    }
    default:
        break;
}

Refer:https://www.codingexplorer.com/loops-switch-statements-ranges-swift/

参考:https : //www.codingexplorer.com/loops-switch-statements-ranges-swift/

回答by hungryMind

Use case statement with defined string or value or use "if else if", in case range is higher

使用带有定义字符串或值的 case 语句或使用“if else if”,以防范围更大