Alternative to switch case in JS/PHP

Switch-hash structures

Fullstack CTO
4 min readMay 11, 2023

Have you ever had a situation where you need to get data from a switch-case block somewhere, and it needs to happen once and it needs to happen somewhere here and now. For example during array initialization? And you don’t want to carry code somewhere, create separate variables which will be used once, create separate structures and put it all into a separate file or a unique space? If yes, you can use objects and/or associative arrays to implement switch-case logic, so-called switch-hash structures.

A typical situation might look something like this in the JS world:

let switchval = 'c'
let somearr = { foo: 1, somevalue: '' }

switch(switchval) {
case 'a': somearr.somevalue = 'foo'
case 'b': somearr.somevalue = 'bar'
default : somearr.somevalue = 'defualt'
}

A little cumbersome, don’t you think? You could have written it like this:

let somearr = {
foo: 1,
somevalue: (function(switchval){
switch(exprvalue) {
case 'a': return 'foo';
case 'b': return 'bar';
default : return 'default';
}
})(switchval)
}

Glory to self-calling anonymous lambda functions. And such code can be often seen in various open-source projects, on githab, in npm modules. But if we can write it that way, why not get rid of IIFEs and replace them with switch-case block with objects or arrays?

Switch-hash implementation in JS

const somevar = { a: 'foo', b: 'bar' }[switchval] || 'default';

// or

const somevar = { a: 'foo', b: 'bar' }[switchval] ?? 'default';

This code does the same thing, but it’s much shorter, faster, and doesn’t use unnecessary constructs.

In case your selection variable is a number, you could use an array:

let switchval = 3;
let somevar = ['a','b'][switchval] ?? 'default';

You don’t need a block, you don’t need a function.

Switch-hash implementation in PHP

In PHP you can also implement switch-array structures, but the specificity of the language adds its own nuances to the implementation:

<?php
$smvr = @['a'=>'foo','b'=>'bar'][$switchval] or $smvr = 'dfault';

And in the same way, in the case of numerical switch-value we use a non-associative array:

<?php
$smvr = @['foo','bar'][$switchval] or $smvr = 'dfault';

In general it is very similar to JS, but there are specifics. First, we use the @ symbol, which is considered bad practice to use, as it were… But the question is when and why. Psychotherapists, when they start treating, the first thing they do is get the person to accept themselves for who they are. ?

If PHP has an error suppression operator, you can use it, if you know what you’re doing. Don’t badmouth the languages you write in. Just accept them for what they are. If you learn the peculiarities of your tool, you can always create reliable fast programs. But it’s offtop, I know people will disagree with me.

So, we have dealt with the error suppression symbol. We’ll move on. In PHP you can use two kinds of logical operators: || and or
And here we immediately stumble upon a question from a PHP interview:

What is the difference between the OR and || operators, and why did we use idiomatic OR instead of character OR in the code above?

You may come across this question on a job interview:

<?php
$a = 0;
$b = 1;

$foo = $a || $b;
$bar = $a or $b;

var_dump($foo, $bar); // ?

What will be output?

If you interview for the php-fullstack position, they will add more JS tasks:

var a = 0, b = 1;
var foo = a || b;

console.log(foo); // ?

Let’s break it down in order.

PHP: $foo = true, $bar = 0
JS: foo = 1

In PHP:

When || is used, first the left hand side is evaluated because it is a left-associative operator, then the right hand side and then the logical OR is evaluated, after which the result is assigned to a variable.

In the case of an OR operator, it is the same, except for the assignment of the result, or rather grouping, which means that no assignment takes place.

$a = 0 or 1;

// alternate for

($a = 0) || 1;

Based on this, you may come across a variation of the problem:

$s = ($a = 0 or 1);
$s = ($a = 0 || 1);

var_dump($s, $a);

The interviewer can change the bracket variations, thereby changing the grouping and behavior of the operators.

Total

  • Switch-hash structures can be used instead of switch-case operators
  • In JS and PHP the result of an OR operator is different.
  • In JS the left-hand side of OR is first calculated and if it’s equivalent to Bool(resultOfCalculation) === false, the right-hand side is returned as is. And this value can be assigned to a variable. For conversions and calculations see https://medium.com/@frontman/9d6f1845ea96.
  • There are two kinds of OR operators in PHP and they have different behavior (|| vs or).
  • In PHP, “||” first calculates the left-hand side, then the right-hand side, and after that it calculates a general logical result which will be passed to the left-hand side of the expression
  • In PHP, the OR operator first calculates the left-hand side, and if it is false, it calculates the right-hand side. It groups the left and right parts, so that without explicitly grouping the expressions, no result of a logical evaluation can be assigned. This feature is used to implement conditional calculations and assignments similar to Bash scripts. For the same reason, we used this operator in switch-hash entries. By the same analogy, you can work with the AND operator and create a short-word IF expression. For example:

An example of a short IF in bash

#!/bin/bash
[ -f 'some.txt' ] && cat 'some.txt'

The same equivalent in PHP

<?php
file_exists('some.txt') and print file_get_contents('some.txt');

Switch-hash using a ternary operator

The logical OR can be replaced by a short ternary operator and then this construction can be made in PHP:

$smvr = ['a'=>'foo','b'=>'bar'][$switchval] ?? 'default';

And yes, this variant is more interesting and shorter. You can say that the main working variant, which is worth using.

--

--