Как использовать диапазоны в выражении case с помощью JavaScript?

Как использовать диапазоны в операторе case с помощью JavaScript? Поэтому, вместо написания кода для каждой возможности, я хотел бы сгруппировать их в диапазонах, например:

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

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

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

   default:
      //doStuffWithAllOthers();
}

Ответ 1

У вас есть как минимум четыре варианта:

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

Если диапазоны большие, это становится громоздким, поэтому вы хотите делать диапазоны. Обратите внимание, что при 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, и есть время, когда это полезно. Операторы case проверяются в порядке на значение, указанное в switch. (И снова, нижние границы могут быть опущены во многих случаях, потому что они бы соответствовали ранее.) Несмотря на то, что case обрабатываются в порядке исходного кода, default может отображаться в любом месте (а не только в конце) и обрабатывается только в том случае, если либо не соответствует case, либо 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
];

... но если значения не являются смежными числами, гораздо проще использовать объект.

Ответ 2

Возможно, это вам нужно?

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

Ответ 3

Диапазоны в этом примере довольно малы, но вот как можно обрабатывать большие диапазоны, согласно документам 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 case with Expressions, но я просто хотел показать еще один пример того, как использовать этот же метод. Я просто сделал это и подумал, что, может быть, кому-то может помочь другой пример, так как я все еще был немного смущен после прочтения других ответов.

Ответ 4

Если ваши диапазоны совпадают и начинаются с 0, вы можете сделать некоторую математику.

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

Например, если вы хотите использовать RED, GREEN и BLUE на карте, например, ваш пример:

  • Диапазон 0-2 соответствует RED
  • Диапазон 3-6 соответствует GREEN
  • Диапазон 7-8 соответствует BLUE

Вы можете написать:

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, и это все равно работает до тех пор, пока предыдущие диапазоны совпадают.

Ответ 5

Чтобы добавить немного разнообразия, особенно если интервалы начинаются с 0, найдите решение с помощью findIndex:

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 будет соответствовать первому

Ответ 6

Используйте оператор case с определенной строкой или значением или используйте "if else if", если диапазон выше

Ответ 7

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/