46

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

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

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

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

   default:
      //doStuffWithAllOthers();
}
4

7 回答 7

113

你至少有四个选择:

1.列出每个case

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.使用if//else ifelse

如果范围很大,那会变得笨拙,所以你想要做范围。请注意,使用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.case与表达式一起使用:

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

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

4.使用调度地图

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

在一些设置代码中:

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

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

    6: doStuffWithThirdRange,
    7: doStuffWithThirdRange
};

然后代替开关:

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

这通过查找要在dispatcher地图上调用的函数来工作,默认为doStuffWithAllOthers如果没有使用奇怪强大的运算符myInterval的特定值的条目,然后调用它。||

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

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

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

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

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

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

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

于 2013-06-17T11:01:13.993 回答
15

此示例中的范围非常小,但根据JavaScript MDN 文档,这是处理更大范围的方法:

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

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

于 2018-02-25T01:26:01.520 回答
6

这可能是你需要的吗?

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

如果您知道范围将非常高(例如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();
}
于 2013-06-17T10:50:46.057 回答
2

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

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

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

  • 范围 0-2 映射到 RED
  • 范围 3-6 映射到绿色
  • 范围 7-8 映射到蓝色

你可以写:

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

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

于 2016-05-13T19:06:00.167 回答
1

为了给已经发布的优秀答案增加一点多样性,特别是当间隔从 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();
}

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

于 2019-07-18T06:31:40.103 回答
-2

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

于 2013-06-17T10:52:52.050 回答
-3

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

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

于 2016-05-19T10:46:17.050 回答