PHP按文件名中的数字排序数组

时间:2017-06-20 18:45:42

标签: php html arrays sorting

我正在制作照片库,根据文件名的编号自动对照片进行排序。

我有以下代码:

//calculate and sort 
$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);


//reset array list
$first = reset($files_thumbs);
$last = end($files_thumbs);
//match and split filenames from array values - image numbers
preg_match("/(\d+(?:-\d+)*)/", "$first", $matches);
$firstimage = $matches[1];
preg_match("/(\d+(?:-\d+)*)/", "$last", $matches);
$lastimage = $matches[1];

但是当我有photo-Aname_0333.jpgphoto-Bname_0222.jpg这样的文件名时,它确实以photo-Aname_0333而不是0222开头。

我如何按文件名编号对其进行排序?

4 个答案:

答案 0 :(得分:1)

usort是一个使用值对数组进行排序的php函数。 usort需要一个接收2个值的回调函数。

在回调中,根据您的需要,您将返回比较1,0或-1的结果。例如,为了对数组asc进行排序,当回调的firts值小于第二个值时,我返回-1。

在这种特殊情况下,我获取文件名的编号,并将其作为字符串进行比较,而不是必须转换为整数。

<?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) {
        return 0;
    }
    return ($firstimage < $lastimage) ? -1 : 1;
});

print_r($photos);

答案 1 :(得分:1)

较早的答案都没有使用最合适/现代的技术进行三向比较-宇宙飞船算子@click.group() @click.pass_context def main(): ctx.ensure_object(dict) @main.command() @click.option('-city', '-c', prompt=True) @click.option('-month', '-m', prompt=True) @click.option('-day_of_week', '-d', prompt=True) @click.pass_context def filter(ctx, city, month, day_of_week): # load filtered data ... # restart the program if click.confirm('Restart to explore another dataset?') if not False: import sys sys.argv.clear() ctx.invoke(filter) )。

它不仅提供整齐的语法,还使您可以在一个步骤中实现多个排序规则。

下面的代码片段将每个文件名字符串分成两半(在下划线上),然后首先比较两个文件名的后一半,如果在第二半部分有平局,则它将比较两个文件名的前一半。

代码:(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);

对于仍然认为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', ) 调用更好的任何人,我将说明我的代码段可能进行了两次比较,而preg_解决方案仅进行了一次。

如果您只想使用一种排序标准,那么这种非正则表达式技术将胜过正则表达式:

preg_

我超级喜欢正则表达式,但是我只知道在非正则表达式技术无法提供有价值的优势时使用它。

答案 2 :(得分:0)

它按字母顺序排序,因为您对文件名使用sort()。代码的第二部分什么都不做。

您可能需要查看我们http://php.net/manual/en/function.usort.php 你可以做点什么

function cmp($a, $b) {
    if ($a == $b) {
        return 0;
    }
    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');

另外,我不确定你的正则表达式,考虑一个名为&#34; abc1234cde2345xx&#34;的文件。我使用的那个在最后的文件扩展名之前取最后一位数字。但这一切都取决于你的文件名。

答案 3 :(得分:0)

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



 //calculate and sort 
$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 and split filenames from array values - image numbers
preg_match("/(\d+(?:-\d+)*)/", "$first", $matches);
$firstimage = $matches[1];
preg_match("/(\d+(?:-\d+)*)/", "$last", $matches);
$lastimage = $matches[1];