Skip to content Skip to sidebar Skip to footer

Php Sort Array By Number In Filename

I am working on a photo gallery that automatically sorts the photos based on the numbers of the file name. I have the following code: //calculate and sort $totaal = 0; if($handle_

Solution 1:

None of the earlier answers are using the most appropriate/modern technique to perform the 3-way comparison -- the spaceship operator (<=>).

Not only does it provide a tidier syntax, it also allows you to implement multiple sorting rules in a single step.

The following snippet break each filename string in half (on the underscore), then compare the 2nd half of both filenames first, and if there is a tie on the 2nd halves then it will compare the 1st half of the two filenames.

Code: (Demo)

$photos = [
    'photo-Bname_0333.jpg', 
    'photo-Bname_0222.jpg',
    'photo-Aname_0333.jpg', 
    'photo-Cname_0111.jpg', 
    'photo-Cname_0222.jpg',
    'photo-Aname_0112.jpg', 
];
usort($photos, function ($a, $b) {
   return array_reverse(explode('_', $a, 2)) <=> array_reverse(explode('_', $b, 2));
});
var_export($photos);

Output:

array (
  0 => 'photo-Cname_0111.jpg',
  1 => 'photo-Aname_0112.jpg',
  2 => 'photo-Bname_0222.jpg',
  3 => 'photo-Cname_0222.jpg',
  4 => 'photo-Aname_0333.jpg',
  5 => 'photo-Bname_0333.jpg',
)

For anyone who still thinks the preg_ calls are better, I will explain that my snippet is making potentially two comparisons and the preg_ solutions are only making one.

If you wish to only use one sorting criteria, then this non-regex technique will outperform regex:

usort($photos, function ($a, $b) {
   return strstr($a, '_') <=> strstr($b, '_');
});

I super-love regex, but I know only to use it when non-regex techniques fail to provide a valuable advantage.

Solution 2:

usort is a php function to sort array using values. usort needs a callback function that receives 2 values.

In the callback, depending of your needs, you will be return the result of the comparision 1, 0 or -1. For example to sort the array asc, I return -1 when the firts value of the callback is less than second value.

In this particular case I obtain the numbers of the filename, and compare it as string, is not necesary to cast as integer.

<?php$photos=[
    'photo-Bname_0222.jpg',
    'photo-Aname_0333.jpg', 
    'photo-Cname_0111.jpg', 

];

usort($photos, function ($a, $b) {

    preg_match("/(\d+(?:-\d+)*)/", $a, $matches);
    $firstimage = $matches[1];
    preg_match("/(\d+(?:-\d+)*)/", $b, $matches);
    $lastimage = $matches[1];

    if ($firstimage == $lastimage) {
        return0;
    }
    return ($firstimage < $lastimage) ? -1 : 1;
});

print_r($photos);

Solution 3:

It sorts alphabetically because you use sort() on the filename. The 2nd part of your code does nothing.

You might want to take a look at usort http://php.net/manual/en/function.usort.php You can do something like

functioncmp($a, $b) {
    if ($a == $b) {
        return0;
    }
    preg_match('/(\d+)\.\w+$/', $a, $matches);
    $nrA = $matches[1];
    preg_match('/(\d+)\.\w+$/', $b, $matches);
    $nrB = $matches[1];

    return ($nrA < $nrB) ? -1 : 1;
}

usort($files_thumb, 'cmp');

Also, I'm not sure about your regex, consider a file named "abc1234cde2345xx". The one I used takes the last digits before a file extension at the end. But it all depends on your filenames.

Solution 4:

sort(array,sortingtype) , you have to set the second parameter of the sort() function to 1 so it will sort items numerically 



 //calculate andsort 
$totaal = 0;
if($handle_thumbs = opendir('thumbs')){
    $files_thumbs = array();
    while(false !== ($file = readdir($handle_thumbs))){
        if($file != "." && $file != ".."){
            $files_thumbs[] = $file;
            $totaal++;
        }
    }
    closedir($handle_thumbs);
}
sort($files_thumbs,1);
//reset array list
$first = reset($files_thumbs);
$last = end($files_thumbs);
//match andsplit filenames from array values - image numbers
preg_match("/(\d+(?:-\d+)*)/", "$first", $matches);
$firstimage = $matches[1];
preg_match("/(\d+(?:-\d+)*)/", "$last", $matches);
$lastimage = $matches[1];

Post a Comment for "Php Sort Array By Number In Filename"