Categories
PHP

Compact `switch` alternative

Some situations in PHP require a set of variables to have values depending on some condition. To achieve such variable-assignment, a switch statement is the traditional GOTO, but PHP’s array syntax combined with the list() language construct. 

For example, if $a==1, then $b=2; $c=2, else if $a==2, then $b=... etc. If the condition is the value of some variable, like $a here, a switch-statement would look like:

switch($a) {
  case 1:
    $b = 2;
    $c = 2;
    break;
  case 2:
    $b = 4;
    $c = 3;
  // etc...
  default:
    $b = 9;
    $c = 9;
}

The number of lines required to express this grows explosively with the number of variables and conditions to set. Instead, use this more elegant way, based on list():

list($b, $c) = [
  1 => [2, 2],
  2 => [4, 3],
  // .. etc
][$a] ?? [9, 9]

Which grows linearly in LoCs with the number of conditions. Other benefits are improved DRY-ness and the guarantee that all variables inlist() are assigned. Note how the default case is implemented as well. 

A simple back of the envelope test with 5 variables and 10 conditions shows the following results. All code was properly indented and formatted. Note also how compressing the list-based approach results in a bigger compression which indicates more DRY-ness. For the sake of testing, a compacted switch-based form, without line-breaks or tabs after assignment is used too. 

characterslinesgzip %
switch-based7237130%
switch-based (compacted)6673132%
list-based3021158%

These tests were simply done by piping the code through the wcandgzip programs. The list-based approach looks as follows:

list($a, $b, $c, $d, $e) = [
        1 => [ 1,  2,  3,  4,  5]
        2 => [ 6,  7,  8,  9, 10]
        3 => [11, 12, 13, 14, 15]
        4 => [16, 17, 18, 19, 20]
        5 => [21, 22, 23, 24, 25]
        6 => [26, 27, 28, 29, 30]
        7 => [31, 32, 33, 34, 35]
        8 => [36, 37, 38, 39, 40]
        9 => [41, 42, 43, 44, 45]
][$x] ?? [46, 47, 48, 49, 50];

The switch-based compact version is as follows:

switch($x) {
        case 1:
                $a =  1; $b =  2; $c =  3; $d =  4; $e =  5;
                break;
        case 2:
                $a =  6; $b =  7; $c =  8; $d =  9; $e = 10;
                break;
        case 3:
                $a = 11; $b = 12; $c = 13; $d = 14; $e = 15;
                break;
        case 4:
                $a = 16; $b = 17; $c = 18; $d = 19; $e = 20;
                break;
        case 5:
                $a = 21; $b = 22; $c = 23; $d = 24; $e = 25;
                break;
        case 6:
                $a = 26; $b = 27; $c = 28; $d = 29; $e = 30;
                break;
        case 7:
                $a = 31; $b = 32; $c = 33; $d = 34; $e = 35;
                break;
        case 8:
                $a = 36; $b = 37; $c = 38; $d = 39; $e = 40;
                break;
        case 9:
                $a = 41; $b = 42; $c = 43; $d = 44; $e = 45;
                break;
        default:
                $a = 46; $b = 47; $c = 48; $d = 49; $e = 50;
}

Check out the one-liner to pick random values from an array. 

In PHP 7.3, you can use array-destructuring to get rid of the `list()` language construct. E.g.: `[$a, $b] = [1, 2];`