I am currently creating a sorting method that consists of values from an mysql query.
Here\'s a brief view of the array:
Array
(
[0]
I am currently creating a sorting method that consists of values from an mysql query.
TRUTH:
Using anything other than MySQL to sort your result set will be less efficient (with php, a usort()
or array_multisort()
call will be more convoluted and harder to maintain) and therefore inappropriate.
SQL: (Demo)
ORDER BY IF(LOCATE('EN', countries), 0, 1), id;
This prioritizes countries
column values that contain EN
then sorts on id
ASC.
For anyone who isn't handling a sql result set or cannot manipulate the query for some reason, I endorse usort()
.
PHP7 offers a beautiful new operator that performs a comparison and returns one of three values (-1, 0, 1). This operator is affectionately called the "spaceship operator" and looks like this <=>
.
PHP: (Demo)
$test = [
['id' => 1, 'countries' => 'EN,CH,SP'],
['id' => 2, 'countries' => 'GE,SP,SV'],
['id' => 3, 'countries' => 'PR,SP,IT'],
['id' => 4, 'countries' => 'EN'],
['id' => 5, 'countries' => 'SP,EN'],
['id' => 6, 'countries' => 'SV,SP,EN'],
['id' => 7, 'countries' => 'GE,SP'],
['id' => 8, 'countries' => 'FR'],
['id' => 9, 'countries' => 'RU,EN'],
['id' => 10, 'countries' => 'EN,SP,IT'],
['id' => 11, 'countries' => 'SP,GR'],
['id' => 12, 'countries' => 'GR,EN']
];
usort($test, function($a, $b) {
return [strpos($a['countries'], 'EN') === false, $a['id']] <=> [strpos($b['countries'], 'EN') === false, $b['id']];
});
var_export($test);
Output:
array (
0 =>
array (
'id' => 1,
'countries' => 'EN,CH,SP',
),
1 =>
array (
'id' => 4,
'countries' => 'EN',
),
2 =>
array (
'id' => 5,
'countries' => 'SP,EN',
),
3 =>
array (
'id' => 6,
'countries' => 'SV,SP,EN',
),
4 =>
array (
'id' => 9,
'countries' => 'RU,EN',
),
5 =>
array (
'id' => 10,
'countries' => 'EN,SP,IT',
),
6 =>
array (
'id' => 12,
'countries' => 'GR,EN',
),
7 =>
array (
'id' => 2,
'countries' => 'GE,SP,SV',
),
8 =>
array (
'id' => 3,
'countries' => 'PR,SP,IT',
),
9 =>
array (
'id' => 7,
'countries' => 'GE,SP',
),
10 =>
array (
'id' => 8,
'countries' => 'FR',
),
11 =>
array (
'id' => 11,
'countries' => 'SP,GR',
),
)
The array elements on either side of the spaceship operator are evaluated from left to right (leftside [0] vs rightside [0], then moving onto the pair of [1] values if there is a "tie" between the two [0] values).
If the === false
looks backwards, let me explain...
If EN
is found in the countries string, the condition will evaluate as false
. When comparing true
and false
, remember that true
equates to 1 and false
equates to 0. We want ASC sorting, so we want to put false outcomes before true outcomes, ergo strings containing EN
need to return false. Hopefully that clears up the logic.