Coderrob brand logo Coderrob

Hi, I'm Rob—programmer, Pluralsight author, software architect, emerging technologist, and lifelong learner.


Clean Up Your Conditionals: Refactoring If-Else with Switch Statements


Sun, 18 Aug 2024

If you’re like me, you’ve probably dealt with your fair share of long, messy deeply nested if-else chains. They can get out of hand pretty fast, right?

One minute you’re making a simple decision, the next you’re wading through a maze of conditions and deeply nested logic. But guess what?

There’s a trick that can help clean this up: using switch and switch(true).

In this post, we’ll take a closer look at how you can use switch statements to break free from the chaos and make your code more readable, more maintainable, and without overloading to your brain juggling the contextual outcomes of each branching statement.

Trust me, it’s one of those small changes that can have a big impact…

Why switch is Worth Your Time

Let’s cut to the chase: switch lets you handle complex conditions in a much cleaner, linear non-nested way. Instead of getting lost in nested if-else blocks, you break it all down into individual cases, which makes it way easier to follow what’s going on.

Not only does this flatten your code, it also makes it easier to maintain and debug when things inevitably need to change (because they always do).

Example 1: Simplifying Basic Conditionals

Let’s start with a simple example. You’ve got a variable dayOfWeek and you want to do different things depending on what day it is. You might have something like this:

if (dayOfWeek == 1) {
  doSomethingOnMonday();
} else if (dayOfWeek == 2) {
  doSomethingOnTuesday();
} else if (dayOfWeek == 3) {
  doSomethingOnWednesday();
}
// ... and so on

You can probably guess where this is going. As the number of days (or conditions) grows, your code becomes harder to read and manage. Luckily the number of days in a week is finite, but for larger systems it can … get bad. Real bad.

Time to switch things up!

Refactoring to switch

By refactoring to use a switch statement instead, you can clean up that if-else tangle. Check this out:

enum DayOfWeek {
  MONDAY = 1,
  TUESDAY = 2,
  WEDNESDAY = 3,
  THURSDAY = 4,
  FRIDAY = 5,
  SATURDAY = 6,
  SUNDAY = 7
}

switch (dayOfWeek) {
  case DayOfWeek.MONDAY:
    doSomethingOnMonday();
    break;

  case DayOfWeek.TUESDAY:
    doSomethingOnTuesday();
    break;

  case DayOfWeek.WEDNESDAY:
    doSomethingOnWednesday();
    break;

  // ... add other days here

  default:
    doSomethingByDefault();
    break;
}

By using an enum, we add some clarity and give those “magic numbers” some actual meaning. So now, instead of wondering what 1 or 2 represents, it’s clear you’re working with days of the week.

This little tweak makes the code easier to read and understand at-a-glance. Something your future self will thank you for, or at least I will if we work together!

Example 2: Handling More Complex Logic

Let’s take spice things up a bit. Say you’ve got a more complex workflow where you’re checking multiple conditions—whether a user is logged in, whether they’re an admin, etc. This could lead to some pretty gnarly nested if-else statements like this:

if (isLoggedIn) {
  if (isAdmin) {
    . . .
    performAdminActions();
  } else if (isUser) {
    . . .
    performUserActions();
  }
} else {
  . . . 
  redirectToLoginPage();
}

Sure, this works, but it’s not the most elegant solution. Nested conditionals can quickly turn into a headache, especially if you need to add more cases later on. Enter switch(true).

Refactoring with switch(true)

Using switch(true) in this scenario can help flatten out the structure and make it more straightforward:

switch (true) {
  case !isLoggedIn:
    redirectToLoginPage();
    break;

  case isAdmin:
    performAdminActions();
    break;

  case isUser:
  default:
    performUserActions();
    break;
}

See how much cleaner that is?

Each condition is treated as its own case, and the logic is easier to read without all the nesting. This also makes it simpler to extend in the future—just add another case when you need to handle a new situation.

NOTE: Added bonus is the default condition forces you to consider edge cases completely obscured by the If-Else noise.

Why It Works

The magic of switch(true) is that it breaks your conditions into bite-sized top-down linear evaluations, making your logic easier to follow. You can think of it as setting up a decision tree where each branch is a distinct case that stands on its own, rather than getting lost in a sea of else ifs.

A few reasons why this works so well:

When to Use switch(true)

Of course, switch(true) isn’t a silver bullet for every situation. It’s most useful when you have multiple boolean expressions or complex combinations of conditions to evaluate. Here are some cases where switch(true) really shines:

Wrap-Up

At the end of the day, writing code isn’t just about just making it “work”—it’s about making it easy to read, understand, and maintain, for both yourself and others. Refactoring with switch(true) is one of those tricks that can help you achieve that by flattening out complex conditional logic into something more digestible.

So next time you find yourself wrestling with a mess of if-else blocks, consider giving switch(true) a shot. It might just be the cleanup your code needs.