Reputation: 779
I have an array which I got from a directory with pdf files in it using scandir
$array = array(7) {
[0]=> string(17) "q150824-spost.pdf"
[1]=> string(17) "s150826-spost.pdf"
[2]=> string(16) "s150826-spro.pdf"
[3]=> string(17) "t150827-spost.pdf"
[4]=> string(16) "t150827-spro.pdf"
[5]=> string(17) "v150825-spost.pdf"
[6]=> string(16) "v150825-spro.pdf"
}
I need to sort the array by the numbers in the file name (eg. 150824
which is actually a date) which I can do using the following:
usort($array, function($a, $b) {
return filter_var($a, FILTER_SANITIZE_NUMBER_INT) - filter_var($b, FILTER_SANITIZE_NUMBER_INT);
});
The above gives me an array sorted by the numbers (which is almost what I want):
$array = array(7) {
[0]=> string(17) "q150824-spost.pdf"
[1]=> string(17) "v150825-spost.pdf"
[2]=> string(16) "v150825-spro.pdf"
[3]=> string(16) "s150826-spro.pdf"
[4]=> string(17) "s150826-spost.pdf"
[5]=> string(17) "t150827-spost.pdf"
[6]=> string(16) "t150827-spro.pdf"
}
However, in addition to this I would also like to sort alphabetically by spost
and spro
(the text before .pdf
) I'm at a loss as to how to achieve this though?
If two strings in the array have the same numbers/date (eg. 150826
) I want to then sort by spost
first and then spro
.
Upvotes: 1
Views: 28
Reputation: 59691
This should work for you:
First just grab the number and the topic name out of the file name with preg_match_all()
and assign it to the variables. After this simply sort it by the topic, if the numbers are equal, otherwise by the numbers.
<?php
usort($arr, function($a, $b){
preg_match_all("/^\w(\d+)-(\w+)/", $a, $mA);
preg_match_all("/^\w(\d+)-(\w+)/", $b, $mB);
$numberA = $mA[1][0];
$numberB = $mB[1][0];
$topicA = $mA[2][0];
$topicB = $mB[2][0];
if($numberA == $numberB){
return strcmp($topicA, $topicB);
}
return $numberA > $numberB ? 1 : -1;
});
print_r($arr);
?>
output:
Array
(
[0] => q150824-spost.pdf
[1] => v150825-spost.pdf
[2] => v150825-spro.pdf
[3] => s150826-spost.pdf
[4] => s150826-spro.pdf
[5] => t150827-spost.pdf
[6] => t150827-spro.pdf
)
Upvotes: 1
Reputation: 2970
Actually you can just do the following
$array =[
"q150824-spost.pdf",
"s150826-spost.pdf",
"s150826-spro.pdf",
"t150827-spost.pdf",
"t150827-spro.pdf",
"v150825-spost.pdf",
"v150825-spro.pdf",
];
usort($array, function($a, $b) {
return filter_var($a, FILTER_SANITIZE_NUMBER_INT) - filter_var($b, FILTER_SANITIZE_NUMBER_INT) + (strlen($b) > strlen($a) ? 1 : 0);
});
print_r($array);
Output
Array
(
[0] => q150824-spost.pdf
[1] => v150825-spost.pdf
[2] => v150825-spro.pdf
[3] => s150826-spost.pdf
[4] => s150826-spro.pdf
[5] => t150827-spost.pdf
[6] => t150827-spro.pdf
)
It is sort by spost first and then spro
Upvotes: 1