DEV Community

Cover image for If (all) else is complicated, switch to switch?

If (all) else is complicated, switch to switch?

Just a little piece of awesome code I picked up at work: replacing an if else statement with a switch!


if(someExpressionA){
  console.log('yes');
} else if (
  someExpressionB && someExpressionC 
  || someExpressionD
) {
  console.log('nope');
} else {
  console.log('maybe');
}

switch(true){
  case someExpressionA: 
    console.log('yes');
    break;
  case someExpressionB 
    && someExpressionC:
  case someExpressionD:
    console.log('nope');
    break;
  default: 
    console.log('maybe');
}

Enter fullscreen mode Exit fullscreen mode

It feels hacky and awesome at the same time ๐Ÿ˜‚ Do you think it's worth using?

Latest comments (29)

Collapse
 
andrewbridge profile image
Andrew Bridge

Switches have the potential to be super powerful, the ability to let conditions fall through...

switch(state) {
    case 'foo':
        console.log('one');
    case 'bar':
        console.log('two');
        break;
    default:
        console.log('three');
}

// When state === 'foo', 'one' and 'two' are logged
Enter fullscreen mode Exit fullscreen mode

...means there are some complex logical flows that could achieved.

But the hidden complexity fall-through case statements add and the ease of missing them means it's far more likely you'll introduce hard to find bugs or regressions.

As a result, most coding styles either warn or actively disallow case statements without a break; statement at the end. Removing that ability removes the key differentiator of a switch statement and makes it a slightly more concise if..else if statement assuming you have a set of conditions checking the same variable for different values. Pretty niche!

Collapse
 
juanfrank77 profile image
Juan F Gonzalez

I think it's worth using. In fact, in the previous enterprise-level project I worked on, 'switch'es were the most prevalent for handling several conditions. If/else's were seldom used.

Collapse
 
johnkazer profile image
John Kazer

Sounds like Ramda cond. Thinking about a switch statement in terms of functions might be an interesting new perspective! This stack overflow piece might help.

Collapse
 
bytebodger profile image
Adam Nathaniel Davis
const yesNoMaybe = (expressionA, expressionB, expressionC) => {
   if (expressionA)
      return 'yes';
   if (expressionA && expressionB || expressionC)
      return 'nope';
   return 'maybe';
}

console.log(yesNoMaybe(expressionA, expressionB, expressionC));
Enter fullscreen mode Exit fullscreen mode
Collapse
 
muhyilmaz profile image
MUHAMMED YILMAZ

switch in c# is more clear. I didn't use in javascript

Collapse
 
haidarknightfury profile image
Haidar

Too many switches is bad design. You may want to switch to proper object oriented principles and this avoid so many ifs.

Collapse
 
trueneu profile image
Pavel Gurkov

It doesnโ€™t bring any value and is more complicated: breaks, their absence, etc. It feels hacky because it is. Itโ€™s a bad thing to be hacky when itโ€™s not needed.

Collapse
 
frontendengineer profile image
Let's Code

can use objects like below, looks very clean

function calculate(operation) {
  const map = {
    add: handleAdd(),
    subtract: handleSubtract(),
    multiply: handleMultiply(),
    divide: handleDivide()
  }

  return map[operation]
} 

const handleAdd = () => {
  // do something magical
}

calculate('add')
Enter fullscreen mode Exit fullscreen mode
Collapse
 
jankapunkt profile image
Jan Kรผster

Little OT here. I think switches are great for revealing unexpected program flows in a multi branch szenario, which is why the exact match condition is so important.

You want your program being as deterministic as possible and therefore throw exceptions when the program deviates at any point. Switches are a nice way to do that:

f = value => {
  case 'foo':
    return stateA()
  case 'bar':
    return stateB()
  default:
    throw new Error(`No state for ${value}`)
}
Enter fullscreen mode Exit fullscreen mode

Relying on truthy/falsy for branching is a great feature of Js but can also lead to false positives / false negatives (think empty Strings, Number 0) that require much more tests than being explicit in the first place.

Collapse
 
andrewbridge profile image
Andrew Bridge

I agree with your initial point, but not necessarily that switches are the answer.

In your example, I'd probably do something like:

const states = {
    foo: stateA,
    bar: stateB
};

const f = (value) => {
    if (!(value in states)) {
        throw new Error(`No state for ${value}`);
    }
    return states[value]();
}
Enter fullscreen mode Exit fullscreen mode

...or more generically assuming things weren't as 1-to-1...

const f = (value) => {
    if (value === 'foo') {
        return stateA();
    }
    if (value === 'bar') {
        return stateB();
    }
    throw new Error(`No state for ${value}`);
}
Enter fullscreen mode Exit fullscreen mode

The second is probably the easiest to understand out of all of them (including the switch imo) so I'd probably lean towards that, but in every case, undefined behaviours are caught appropriately.

Collapse
 
ohryan profile image
Ryan

TBH I've never considered doing this but now that I see it, it feels like an abuse of the switch statement.

Neither example seems particularly "clean" to me.

My preference would be to refactor this code such that you can return early.

function getLogMessage() {
    if (someExpressionA) {
        return 'yes';
    }

    if (someExpressionB && someExpressionC || someExpressionD) {
        return 'nope';
    }

    return 'maybe';
}

console.log(getLogMessage())
Enter fullscreen mode Exit fullscreen mode

Much more straightforward than either IMHO.

Collapse
 
branzz profile image
Branzz

Which can, in turn, be simplified by Java 13's Enhanced Switch statement (or even a ternary statement at that point).

console.log(switch(true) {
    case someExpressionA -> "yes";
    case someExpressionB && someExpressionC || someExpressionD -> "nope";
    default -> "maybe";
});
Enter fullscreen mode Exit fullscreen mode
Collapse
 
jmdejager profile image
๐Ÿค๐Ÿฅ‡ Jasper de Jager

Thnx for sharing! Honored to be your first comment ๐Ÿ˜Š๐Ÿ˜‰

Collapse
 
jmdejager profile image
๐Ÿค๐Ÿฅ‡ Jasper de Jager

I agree, the console.log was purely for the example. I also think most people will agree with you, my first feeling was also that it feels hacky. But... There are people that do use it, so it is good to know it exists ๐Ÿ™‚

Collapse
 
sargalias profile image
Spyros Argalias

I think it depends.

If it looks cleaner to you and your team, then that's the answer (use it).

Personally, I have a slight preference to normal if / else statements because:

  • in JavaScript (the language I use at work), the switch statement wouldn't work unless each expression was explicitly true or false. Whereas if / else statements also work with "truthy" or "falsy" values. For example if ('hello' && 'goodbye') passes, because non-empty strings are truthy, but switch(true) { case 'hello' && 'goodbye': } wouldn't pass.
  • I'm not used to using switch statements like that, so they might catch me out until I get used to them (and others too). If they were the standard convention, then it wouldn't be a problem. As they say, convention over perfection, although this is a very small change in this case.
  • More realistically, I don't encounter long conditionals often. Short conditionals don't seem like a great use case for switch statements. For example:
if (!condition) {
  return foo();
}
return bar();
Enter fullscreen mode Exit fullscreen mode

In summary. It's not my cup of tea. But it's not a big change, so I would do it if that's what the team preferred. If you and your team like it, then by all means use it :).

Collapse
 
jmdejager profile image
๐Ÿค๐Ÿฅ‡ Jasper de Jager • Edited

I get what you you're saying only

if ('hello' && 'goodbye')

isn't actually checking anything I guess.
The rest are sure valid points! ๐Ÿ˜Š thnx for sharing

Collapse
 
sargalias profile image
Spyros Argalias

Fair point lol. Off the top of my head I use them sometimes to check for empty strings and stuff :). No problem, thanks for sharing the tip.

Collapse
 
hey_yogini profile image
Yogini Bende

I totally agree with the first point. If you have truthy and falsy value you should prefer if but for long strict conditions, switch can be preferable.

Collapse
 
dantederuwe profile image
Dante De Ruwe • Edited

Coincidentally, a friend of mine told me this week his switch(true) did not pass his code review, despite the arguments of it looking much clearer. Some people will not accept this, so beware ๐Ÿ˜›

Collapse
 
moopet profile image
Ben Sinclair

Because anyone who isn't used to seeing it will think it's a typo and then have to rethink what the function is doing.

Collapse
 
jmdejager profile image
๐Ÿค๐Ÿฅ‡ Jasper de Jager

But what if it is more common. At some point you would expect a turning point if there are no other downsides ofcourse.

Thread Thread
 
moopet profile image
Ben Sinclair

Generally I think people are trying to move away from functions that have a lot of conditionals, so it's probably not going to become more common.

Thread Thread
 
jmdejager profile image
๐Ÿค๐Ÿฅ‡ Jasper de Jager

good point, not a fan of them myself ๐Ÿ˜‰

Collapse
 
hey_yogini profile image
Yogini Bende

Would like to understand the reason for not allowing switch (if you can share). Because. even I have started using switch over if-else in many cases. It just make more sense to me.

Collapse
 
jmdejager profile image
๐Ÿค๐Ÿฅ‡ Jasper de Jager

I think it is because it takes an extra thinking step.
if/else-if is more easily read as a sentence. But please let me know if there are other reasons.

Thread Thread
 
thalitadev profile image
Thalita G. • Edited

Just a bit of a guess here, but I think the switch statement is considered a last resort when you have a ton of conditionals that can't be done any other way.

The switch statement may be like a logic shortcut when there may be another solution out there. Sometimes if/else is sufficient and reads easier when you really don't have that many statements. Sometimes a quick if like if (!someExpressionA) { return console.log('yes') } may be a less intensive solution. And some people just don't like using conditionals at all and prefer to use objects whenever they can.

I kinda use all four solutions depending on the situation, so maybe @dantederuwe 's friend didn't pass because there was a better solution. Just a total guess of course!

Collapse
 
jmdejager profile image
๐Ÿค๐Ÿฅ‡ Jasper de Jager • Edited

hence my question, should I use it ๐Ÿ˜

Collapse
 
chethanprabhu profile image
Chethan Prabhu

It's pretty straight forward. But I never thought of it ๐Ÿ˜‚ good tiny trick!

Collapse
 
jmdejager profile image
๐Ÿค๐Ÿฅ‡ Jasper de Jager

Got it from a colleague of mine, had to share it ๐Ÿ˜Š