0

I recently completed a problem in CodeWars using an if-else statement, but I wanted to retry it and use a switch statement instead. Too bad that it is not working the way that I thought it would!

The problem I am solving is to take in a distance(s) that an Ironman triathlon athlete has completed and return an object that shows a key based on whether the athlete should be Swimming, Biking or Running with a value of the length of the race to go.

My If-Else Solution:

function iTri(s) {  
  var triLength = 140.60;  
  var result = {};  
  var str = ' to go!';  
  var lengthLeft = (triLength - s).toFixed(2);  

  if (s === 0) {
    return 'Starting Line... Good Luck!';
  } else if (s <= 2.4) {
    result.Swim = lengthLeft + str;
  } else if (s <= 114.4) {
    result.Bike = lengthLeft + str;
  } else if (s < 130.60) {
    result.Run = lengthLeft + str;
  } else if (s < 140.60) {
    result.Run = 'Nearly there!';
  } else {
    return 'You\'re done! Stop running!';
  }
  return result;
  }

The (non-working) Switch statement:

function iTri(s){
  let tri = (2.4 + 112 + 26.2).toFixed(2);
  let left = tri - s;
  let str = ' to go!'
  let result = {};

  switch(s) {
    case (s === 0):
      return "Starting Line... Good Luck!";
      break;
    case (s <= 2.4):
      result.Swim = left + str;
      return result;
      break;
    case (s <= 114.4):
      result.Bike = left + str;
      return result;
      break;
    case (s <= 130.60):
      result.Run = left + str;
      return result;
      break;
    case (s < 140.60):
      result.Run = 'Nearly there!';
      return result;
      break;
    default:
      return 'You\'re done! Stop running!';
  }
}

These are the tests:

Test.describe("Example tests",_=>{
Test.assertSimilar(iTri(36),{'Bike':'104.60 to go!'});
Test.assertSimilar(iTri(103.5),{'Bike':'37.10 to go!'});
Test.assertSimilar(iTri(2),{'Swim':'138.60 to go!'});
});

And the Output:

✘ Expected: '{ Bike: \'104.60 to go!\' }', instead got: '\'You\\\'re done! Stop running!\''
✘ Expected: '{ Bike: \'37.10 to go!\' }', instead got: '\'You\\\'re done! Stop running!\''
✘ Expected: '{ Swim: \'138.60 to go!\' }', instead got: '\'You\\\'re done! Stop running!\''  

Also is it worth it to convert it to a switch statement? What are benefits/drawbacks of doing it as if/else vs switch?

Jon Langel
  • 157
  • 1
  • 2
  • 11
  • 1
    You're not using `case` right. `switch(s)` means that `case n` is the same as `if (s === n)`. – Eli Sadoff Nov 28 '16 at 17:35
  • It's possible to make a `switch` work, but it's an awkward thing to do. The `switch` statement is really for comparing a value to particular, discrete possibilities, not ranges. – Pointy Nov 28 '16 at 17:35
  • What would be the alternative to switch(s) that would allow it to work? @EliSadoff – Jon Langel Nov 28 '16 at 17:37
  • You can do this with a switch like is done [here](http://stackoverflow.com/questions/5619832/switch-on-ranges-of-integers-in-javascript), but it's awkward. – Eli Sadoff Nov 28 '16 at 17:38
  • 1
    @EliSadoff it looks like based off that example I would have to create multiple switch statements for each key I want to add to the object. That doesn't sound worth it! Thank you – Jon Langel Nov 28 '16 at 17:41
  • @Pointy Thank you! You are definitely right, after looking at the example that Eli gave it would be a lot more work to recreate a switch statement out of it. – Jon Langel Nov 28 '16 at 17:41
  • 1
    Just as an aside, the `break` statement after a `return` statement is completely unnecessary. The `return` breaks out of the `switch` statement just as much as a `break` statement would. – Ted Hopp Nov 28 '16 at 17:47
  • I will be sure to remember that for the next time I create a switch statement, Thanks! @TedHopp – Jon Langel Nov 28 '16 at 17:49

2 Answers2

1

Is it even worth it to try to convert it to a switch statement?

No. switch is only useful if you have multiple exact matches. This is not the case for you.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • 1
    While technically correct, I think you can turn the problem around to use a **switch** – JonSG Nov 28 '16 at 18:42
  • @JonSG Yes, you could also turn it around and use `while` statements instead of the `if`s. But that wouldn't be useful either. Matching a constant against multiple dynamic expressions is not what `switch` was made for, and cannot be optimised either. It only makes the code longer and less readable. – Bergi Nov 28 '16 at 18:57
0

If you turn the problem around slightly then you can use a switch like this. Your switch is very close to this already

function iTri(s) {  
  var triLength = 140.60;  
  var result = {};  
  var str = ' to go!';  
  var lengthLeft = (triLength - s).toFixed(2);  

  switch(true) {
      case s === 0:
        return 'Starting Line... Good Luck!';
      case s <= 2.4:
        result.Swim = lengthLeft + str;
        break;
      case s <= 114.4:
        result.Bike = lengthLeft + str;
        break;
      case s < 130.60:
        result.Run = lengthLeft + str;
        break;
      case s < 140.60:
        result.Run = 'Nearly there!';
        break;
      default:
        return 'You\'re done! Stop running!';
  }
  
  return result;
}

console.log(iTri(0));
console.log(iTri(2));
console.log(iTri(50));
console.log(iTri(120));
console.log(iTri(135));
console.log(iTri(145));
JonSG
  • 10,542
  • 2
  • 25
  • 36