web-dev-qa-db-fra.com

Comment utiliser des plages dans une instruction de cas de commutation en utilisant JavaScript?

Comment utiliser des plages dans une instruction de cas de commutation en utilisant JavaScript? Ainsi, au lieu d'écrire du code pour chaque possibilité, j'aimerais les regrouper par plages, par exemple:

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

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

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

   default:
      //doStuffWithAllOthers();
}
28
Lave Loos

Vous avez au moins quatre options:

1. Listez chaque case

Comme indiqué par LightStyle , vous pouvez lister explicitement chaque cas:

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

Si les plages sont grandes, cela devient difficile à manier, vous voudrez donc en faire. Notez qu'avec if...else if...else if, vous n'obtenez pas les versions les plus récentes si une version antérieure correspond, il vous suffit donc de spécifier la limite supérieure à chaque fois. Je vais inclure la limite inférieure dans /*...*/ par souci de clarté, mais vous la laisseriez normalement pour éviter d'introduire un problème de maintenance (si vous incluez les deux limites, il est facile de changer l'une et d'oublier de changer l'autre):

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. Utilisez case avec les expressions:

JavaScript est inhabituel en ce sens que vous pouvez utiliser des expressions dans l'instruction case pour nous permettre d'écrire la séquence if...else if...else if ci-dessus sous la forme d'une instruction 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();
}

Je ne préconise pas cela, mais est une option en JavaScript, et il est parfois utile. Les instructions case sont vérifiées dans l'ordre par rapport à la valeur que vous donnez dans switch. (Et encore une fois, les limites inférieures pourraient être omises dans de nombreux cas car elles auraient déjà correspondu auparavant.) Même si les cases sont traités dans l'ordre du code source, le default peut apparaître n'importe où (pas seulement à la fin) et n'est traité que si aucun cases correspond ou un case correspondant et est tombé à la valeur par défaut (n'a pas eu de break; il est rare que vous vouliez faire cela, mais ça arrive).

4. Utilisez une carte de répartition

Si vos fonctions prennent toutes les mêmes arguments (et cela pourrait ne pas être des arguments, ou tout simplement les mêmes), une autre approche est une carte de dispatch:

Dans certains codes d'installation:

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

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

    6: doStuffWithThirdRange,
    7: doStuffWithThirdRange
};

Puis au lieu de l'interrupteur:

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

Cela fonctionne en cherchant la fonction à appeler sur la carte dispatcher, par défaut à doStuffWithAllOthers s'il n'y a pas d'entrée pour cette valeur spécifique myInterval en utilisant le curieusement-puissant || opérateur , puis en l'appelant.

Vous pouvez diviser cela en deux lignes pour le rendre un peu plus clair:

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

J'ai utilisé un objet pour une flexibilité maximale. Vous pourriez définir dispatcher comme ceci avec votre exemple spécifique:

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

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

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

... mais si les valeurs ne sont pas des nombres contigus, il est beaucoup plus clair d'utiliser un objet à la place.

75
T.J. Crowder

Est-ce peut-être ce dont vous avez besoin?

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

Si vous savez que la plage va être très élevée (par exemple, 0-100), vous pouvez également le faire, ce qui est sûrement plus simple, plus propre et plus simple:

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

Les plages de cet exemple sont plutôt petites, mais voici comment gérer des plages plus grandes, selon le 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;
}

Je sais que ce style a déjà été montré par T.J. Crowder via Utilisez case avec des expressions, mais je voulais juste montrer un autre exemple d'utilisation de cette même méthode. Je viens de faire cela et j'avais pensé qu'un autre exemple pourrait peut-être aider quelqu'un, car j'étais encore un peu confus après avoir lu d'autres réponses.

3
twknab

Si vos plages sont les mêmes et commencent à 0, vous pouvez faire des calculs. 

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

Par exemple, si vous souhaitez RED, GREEN et BLUE sur la carte, comme dans votre exemple:

  • Plage 0-2 correspond au ROUGE
  • Plage 3-6 cartes en VERT
  • Plage 7-8 cartes en BLEU

Tu peux écrire:

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

Notez que la dernière plage dans l'exemple est 2, pas 3 et cela fonctionne toujours tant que les plages précédentes sont les mêmes.

2
iamdimitar

Pour ajouter un peu de diversité aux excellentes réponses déjà postées, d'autant plus que les intervalles commencent par 0, voici une solution avec findIndex ( Yeah 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();
}

Comme le tableau range est ordonné, findIndex correspondra au premier. Selon la manière dont vous nommez vos plages, en indiquant 0 ou 1, vous devrez peut-être supprimer le premier 0 dans range.

0
Al-un

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

Voir:https://www.codingexplorer.com/loops-switch-statements-ranges-Swift/

0