Tomasz's suggestion of array_multisort() is a clever, declarative, and concise technique that has been available in php versions for many years. I'd likely use array_multisort()
if this task was in my project.
I might suggest, for project stability (in case the data structure is extended/changed), to explicitly name the column to be sorted by. The following snippet also avoids making iterated end()
calls.
array_multisort(array_column($array, 'cat_url_title'), SORT_NUMERIC, $array);
I'll show a couple of modern alternatives as an academic exercise.
From PHP7, the spaceship operator also provides a concise syntax. To isolate the numeric substring before the first hyphen cast the strings as integers.
usort($array, function($a, $b) {
return (int)$a['cat_url_title'] <=> (int)$b['cat_url_title'];
});
From PHP7.4, arrow function syntax makes a usort()
call more concise, but arguably more cryptic to read if you are not used to the syntax.
usort($array, fn($a, $b) => (int)$a['cat_url_title'] <=> (int)$b['cat_url_title']);
As with nearly all of my php posts, here is an online demo to prove that all of my snippets function as intended.
Snippets on this page that iterate the input array multiple times should be avoided.
p.s. if you wish to sort the cat_url_title
values on the four numeric/alphabetic substrings, you can write these substrings as arrays on each side of the spaceship operator and it will evaluate the substrings from left to right to determine the sorting outcomes.
Code: (Demo)
usort($array, function($a, $b) {
return (preg_match_all('~[a-z]+|\d+~', $a['cat_url_title'], $out) ? $out[0] : ['','','',''])
<=>
(preg_match_all('~[a-z]+|\d+~', $b['cat_url_title'], $out) ? $out[0] : ['','','','']);
});
p.p.s. This is may a good case for version_compare()
. Unfortunately, it is not reliable for the strings in my test battery. Take note of the final position of the 16-a-20n
subarray in this demo. I believe that the function is ignoring the final letter because the evaluation is 0
between 16-a-20m
and 16-a-20n
.
As for your sample strings with consistent a
and m
substring positions, it works perfectly to naturally sort.
Code: (Demo)
usort($array, function($a, $b) {
return version_compare($a['cat_url_title'], $b['cat_url_title']);
});