PHP Custom array sort filenames by year and month, newest first
I've got an array of files which looks like this:
array (
0 => 'scpt-01-2010.phtml',
1 => 'scpt-01-2011.phtml',
2 => 'scpt-02-2010.phtml',
3 => 'scpt-02-2011.phtml',
4 => 'scpt-03-2010.phtml',
5 => 'scpt-04-2010.phtml',
6 => 'scpt-05-2010.phtml',
7 => 'scpt-06-2010.phtml',
8 => 'scpt-07-2010.phtml',
9 => 'scpt-08-2010.phtml',
10 开发者_运维技巧=> 'scpt-09-2010.phtml',
11 => 'scpt-10-2010.phtml',
12 => 'scpt-11-2010.phtml',
13 => 'scpt-12-2010.phtml',
);
How can I sort it so that 2011 files appear first, in order of month (so it should lead with scpt-02-2011.phtml)?
I've tried the main sorting functions like natsort, rsort, arsort etc but I'm not getting anywhere fast!
Thanks in advance.
function customSort($a, $b) {
// extract the values with a simple regular expression
preg_match('/scpt-(\d{2})-(\d{4})\.phtml/i', $a, $matches1);
preg_match('/scpt-(\d{2})-(\d{4})\.phtml/i', $b, $matches2);
// if the years are equal, compare by month
if ($matches2[2] == $matches1[2]) {
return $matches2[1] - $matches1[1];
// otherwise, compare by year
} else {
return $matches2[2] - $matches1[2];
}
}
// sort the array
usort($array, 'customSort');
This method uses usort()
to sort the array, passing the name of our comparison function.
http://php.net/usort
Use usort(), it allows you to write your own callback and sort your own way.
There is no need to roll out the regex engine for this task. You need to explode on the hyphens, compare the elements in reverse order, and sort in descending order. The following translates rather literally as long as you understand that return $b <=> $a;
means "sort descending". Since all of your file extensions are the same, the extensions may remain attached to the year value without damaging accuracy.
Code: (Demo)
$files = [
0 => 'scpt-01-2010.phtml',
1 => 'scpt-01-2011.phtml',
2 => 'scpt-02-2010.phtml',
3 => 'scpt-02-2011.phtml',
4 => 'scpt-03-2010.phtml',
5 => 'scpt-04-2010.phtml',
6 => 'scpt-05-2010.phtml',
7 => 'scpt-06-2010.phtml',
8 => 'scpt-07-2010.phtml',
9 => 'scpt-08-2010.phtml',
10 => 'scpt-09-2010.phtml',
11 => 'scpt-10-2010.phtml',
12 => 'scpt-11-2010.phtml',
13 => 'scpt-12-2010.phtml',
];
usort($files, function ($a, $b) {
return array_reverse(explode('-', $b, 3)) <=> array_reverse(explode('-', $a, 3));
});
var_export($files);
Output:
array (
0 => 'scpt-02-2011.phtml',
1 => 'scpt-01-2011.phtml',
2 => 'scpt-12-2010.phtml',
3 => 'scpt-11-2010.phtml',
4 => 'scpt-10-2010.phtml',
5 => 'scpt-09-2010.phtml',
6 => 'scpt-08-2010.phtml',
7 => 'scpt-07-2010.phtml',
8 => 'scpt-06-2010.phtml',
9 => 'scpt-05-2010.phtml',
10 => 'scpt-04-2010.phtml',
11 => 'scpt-03-2010.phtml',
12 => 'scpt-02-2010.phtml',
13 => 'scpt-01-2010.phtml',
)
To rephrase, for a file like scpt-02-2011.phtml
, the explosion creates:
['scpt', '02', '2011.phtml']
then it is reversed to become:
['2011.phtml', '02', 'scpt']
then each element is progressively compared against the other filename's respective element in a DESC fashion.
精彩评论