Is a Switch within an Else possible?

Asked

Viewed 601 times

2

I’m trying to make a site where the player can calculate the status of his character automatically to streamline at chip time, character creation and no mistakes.

So I made the following code (using jQuery), depending on the entered value, already automatically calculates the mod (modifier) and the rank of your skill. However, I’m not able to make it work, only works my first if() and only the Default that I set in switch(), I wonder why it’s not working.

$('#str').on('input', function() {
  let modificador = $('.str-mod');
  let rank = $('.str-rank');

  if (this.value == '' || this.value <= 0) {
    rank.text('F');
    modificador.text('-10 ');
  } else {

    let modificadorStatusBase = -5;
    let modificadorBase = Math.floor(this.value / 2) + modificadorStatusBase;

    modificador.text((modificadorBase < 0 ? '' : '+') + modificadorBase + ' ');

    switch (this.value) {
      case this.value >= 4 && this.value <= 9:
        rank.text('D');
        break;
      case this.value >= 10 && this.value <= 15:
        rank.text('C');
        break;
      case this.value >= 16 && this.value <= 21:
        rank.text('B');
      default:
        rank.text('E');
        break;
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="div-pontos">
  <fieldset>
    <legend>Status</legend>
    <form class="form-pontos">

      <div>
        <input type="text" nome="str" id="str" placeholder="Força" value="22" maxlength="3">
        <br>
        <label for="str">[
          <span class="str-mod">+6 </span>
          <span class="str-rank">A</span> ] Str (Força)
        </label>
      </div>
    </form>
  </fieldset>
</div>

https://jsfiddle.net/9obtwds1/1/

3 answers

9

Citing the English stackoverflow response -> https://stackoverflow.com/a/2697105/10577440

The switch works by comparing what is in the switch() with what is in each case:

switch (valor) {
    case 1: ....
    case 2: ....
    case 3: ....
}

So there can be no logic within case.

A code like that:

switch (valor) {
    case (valor >= 10 && valor <= 20): ...
}

is equivalent to that:

if (valor === (valor >= 10 && valor <= 20)) ...

In this case it is recommended to use if-Else :)

  • 3

    It is worth remembering that by not using the loose comparison, but yes ===, the result of the expression (valor === (valor >= 10 && valor <= 20)) will never be true if the type of valor is not boolean. In fact, it will be valid only if valor = false, which makes no sense at all in this case - which explains why we always enter the default when used switch(valor).

4


Your switch is wrong, so you can use one between switch should use a structure like this:

switch (true) {
  case (this.value >= 4 && this.value <= 9):
    rank.text('D');
    break;
  case (this.value >= 10 && this.value <= 15):
    rank.text('C');
    break;
  case (this.value >= 16 && this.value <= 21):
    rank.text('B');
  default:
    rank.text('E');
    break;
}

Or simply a if/else:

if (this.value >= 4 && this.value <= 9) {
  rank.text('D');
} else if (this.value >= 10 && this.value <= 15) {
  rank.text('C');
} ...

As very well remembered by Andersoncarloswoss in the comments: "if there is the condition value <= 9, there will be no need to compare value >= 10 since the above condition already guarantees that the value is greater than 9". So it’s possible to create a structure like this:

switch (true) {
  case (this.value <= 3):
    rank.text('E');
    break;
  case (this.value <= 9):
    rank.text('D');
    break;
  case (this.value <= 15):
    rank.text('C');
    break;
  case (this.value <= 21):
    rank.text('B');
    break;
  default:
    rank.text('E');
    break;
}

Or, with if/else

if (this.value <= 3) {
  rank.text('E');
} else if (this.value <= 9) {
  rank.text('D');
} else if (this.value <= 15) {
  rank.text('C');
} ...
  • 4

    In this case I would use if/Else if. So that a switch on top of nothing?

  • @bfavaretto agree, but if the questioner wants to use the switch, either because he is studying or because he thinks more readable, this is the way

  • 1

    The operator switch is for comparing equalities. Internally it uses the comparator ===. The correct is to use the logical structure if else to solve the problem.

  • 1

    @Victorcarnaval in my answer he compares true with the result of comparing each case, it is a way to use the switch for that purpose

  • 2

    Just remember that in many cases conditions can be simplified. For example, if there is the condition value <= 9, there will be no need to compare value >= 10 since the above condition already guarantees that the value is greater than 9.

  • @Andersoncarloswoss very well remembered, I edited the answer with a better solution

Show 1 more comment

1

Really use a switch find unnecessary in this case. You can make a sequence of if else and finally a else (when none of the conditions of if else have been met). You can even simplify the code by making changes to the texts at the end, all at once.

You can store the field value in a variable, without having to repeat this.value several times:

let val = parseInt(this.value.trim());

First I eliminated spaces on the edges with .trim(). This means that if only spaces are entered in the field, the value will be empty. Then I converted to integer with parseInt(), so that it converts the value into number instead of string. This makes a difference in the 0, because 0 type number is different from 0 string, which will be used in if.

The code would look like this:

$('#str').on('input', function() {

   let modificador = $('.str-mod');
   let rank = $('.str-rank');
   let val = parseInt(this.value.trim());
   var rtxt, mtxt;
   
   if (!val || isNaN(val) || val < 0) {
      rtxt = 'F';
      mtxt = '-10 ';
   } else if (val >= 4 && val <=9) {
      rtxt = 'D';
   } else if (val >= 10 && val <= 15) {
      rtxt = 'C';
   } else if (val >= 16 && val <= 21) {
      rtxt = 'B';
   } else {
      rtxt = 'E';
   }

   if(rtxt != "F"){
      let modificadorStatusBase = -5;
      let modificadorBase = Math.floor(val / 2) + modificadorStatusBase;
      mtxt = (modificadorBase < 0 ? '' : '+') + modificadorBase + ' ';
   }
   
   rank.text(rtxt);
   modificador.text(mtxt);
   
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="div-pontos">
  <fieldset>
    <legend>Status</legend>
    <form class="form-pontos">

      <div>
        <input type="text" nome="str" id="str" placeholder="Força" value="22" maxlength="3">
        <br>
        <label for="str">[
          <span class="str-mod">+6 </span>
          <span class="str-rank">A</span> ] Str (Força)
        </label>
      </div>
    </form>
  </fieldset>
</div>

In the first if:

if (!val || isNaN(val) || val < 0) {

checking:

!val       -> se o valor é vazio ou igual a 0
isNaN(val) -> não é um número (no caso de se digitar algo que não seja número)
val < 0    -> se for um número negativo

After the if else put another if:

if(rtxt != "F"){

As only the first condition of the first if modifies the variable element text modificador differently from the other conditions, I checked the value of the variable rtxt (which will be the variable element text rank) is different from F.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.