Compact `switch` alternative
Some situations in PHP require a set of variables to have values depending on some condition. To achieve such 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 list()
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.
characters | lines | gzip % | |
switch-based | 723 | 71 | 30% |
switch-based (compacted) | 667 | 31 | 32% |
list-based | 302 | 11 | 58% |
These tests were simply done by piping the code through the wc
and gzip
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];