If statements: Do you really need them in your code?

- select the contributor at the end of the page -

An if statement lets your program know whether or not it should execute a block of code. And while there's nothing really wrong with using if statements, it can help to avoid them when possible. I think that avoiding if statements can actually help make the code a bit more readable to humans, but I'd like to hear what you think about this issue.

I've included some examples below. Check them out and let me know if you agree; arguments in favor of if statements are more than welcome, so fire away. Since this is not about imperative versus declarative programming, let's keep it simple and take a look at a few examples on how we can write code in certain cases without the use of conditionals (if, switch, ternaries).

Of course, writing without if statements might not always be the right answer. In fact, sometimes trying to avoid an if statement will make the code less readable. On the other hand, if someone challenges you to solve something without using if statements, you'll see that there's always a way.

Example 1: Count the odd numbers in an arrayOfNumbers:

// Example input

let arrayOfNumbers = [1,4,5,9,0,-1,5];

// ***********

// Instead of:

// ***********

let counter1 = 0;

arrayOfNumbers.forEach(number => {

let remainder = Math.abs(number%2);

if (remainder === 1) {

counter1++;

}

});

console.log(counter1);

// ***********

// How about:

// ***********

let counter2 = 0;

arrayOfNumbers.forEach(number => {

let remainder = Math.abs(number%2);

counter2 = counter2 + remainder;

});

console.log(counter2);

In this example, we're taking advantage of the fact that the result of modulus 2 operation is always either 1 (for odd) or 0 (for even).

Example 2: Write a function that takes a date object argument, and returns the string "weekend" or "weekday"

// ***********

// Instead of:

// ***********

let weekendOrWeekday1 = inputDate => {

let day = inputDate.getDay();

if (day === 0 || day === 6) {

return "weekend";

} else {

return "weekday";

}

// Or, for ternary fans:

 // return (day === 0 || day === 6) ? "weekend" : "weekday";

};

console.log(weekendOrWeekday1(new Date()));

// ***********

// How about:

// ***********

let weekendOrWeekday2 = inputDate => {

let day = inputDate.getDay();

let labels = { 0: "weekend", 6: "weekend", default: "weekday" };

return labels[day] || labels['default'];

};

console.log(weekendOrWeekday2(new Date()));

Did you notice that the if statement condition has some data in it? It tells us which days are weekends. We'll watch for this pattern, extract the data presented in the if statement into an object, and use that instead.

Example 3: (A bit more advanced) Write the function doubler; based on the type of input, it will do the following:

When the input is

  • A number, it doubles it (i.e. 5 => 10, -10 => -20)
  • A string, it repeats every letter (i.e. 'hello' => 'hheelloo')
  • A function, it calls it twice
  • An array, it calls itself on all elements of that array
  • An object, it calls itself on all the values of that object

// ***********

// Instead of:

// ***********

let doubler1 = input => {

switch(typeof input) {

case "number":

     return input + input;

case "string":

     return input.split('').map(letter => letter + letter).join('');

case "object":

     Object.keys(input).map(key => input[key] = doubler1(input[key]));

return input;

case "function":

     input();

input();

}

};

console.log(doubler1(-10));

console.log(doubler1('hey'));

console.log(doubler1([5, 'hello']));

console.log(doubler1({a: 5, b: 'hello'}));

console.log(doubler1(function() { console.log('callme'); }));

// ***********

// How about:

// ***********

let doubler2 = input => {

let operationsByType = {

'number': input => input + input,

'string': input => input.split('').map(letter => letter + letter).join('');

'function': input => { input(); input(); },

'object': input => {

Object.keys(input).map(key => input[key] = doubler2(input[key]));

return input;

}

};

return operationsByType[typeof input](input);

};

console.log(doubler2(-10));

console.log(doubler2('hey'));

console.log(doubler2([5, 'hello']));

console.log(doubler2({a: 5, b: 'hello'}));

console.log(doubler2(function() { console.log('callme'); }));

Again, notice how the data (which operations should be done for which type) was all extracted out of the switch statement into an object, then the object was invoked with the correct parameter.

So, now that you've seen a few examples omitting the if statement, what are your thoughts? Do you have any arguments in favor or against either of these two coding styles?

Get our content first. In your inbox.

Loading form...

If this message remains, it may be due to cookies being disabled or to an ad blocker.

Contributor

Samer Buna

is a senior software developer, Pluralsight author and instructor at CodingHouse. Samer has been writing Rails applications since well before Rails was 1.0, and his favorite frontend framework is React with Flux. In his spare time, Samer helps entrepreneurs validate their startup ideas in the market. You can follow him on Twitter @samerBuna.