简体   繁体   English

按自然降序对目录文件名数组进行排序

[英]Sorting an array of directory filenames in descending natural order

I have a content directory to be returned in descending natural order.我有一个按自然降序返回的内容目录。

I'm using scandir() and natsort() , but the addition of array_reverse() yields no results.我正在使用scandir()natsort() ,但添加array_reverse()没有产生任何结果。

I've been researching using a combination of opendir() and readdir() as well what ever else to affect this outcome.我一直在研究使用opendir()readdir()的组合以及其他什么会影响这个结果。

The items to be sorted are numbered image files.要排序的项目是编号的图像文件。 They are to be returned as: 10 9 8 7 and so on, but like from like 1000 999 998 997 ... until 0它们将被返回为: 10 9 8 7等等,但就像从1000 999 998 997 ... 直到0

Here's my current code:这是我当前的代码:

$dir = 'dead_dir/dead_content/';
$launcher = scandir($dir);
natsort($launcher);
array_reverse($launcher, false);
foreach ($launcher as $value) {
    if (in_array(pathinfo($value, PATHINFO_EXTENSION), array('png'))) {
        echo '<img src="dead_dir/dead_content/'.$value.'" />'
    }
}

The problem is simple.问题很简单。 array_reverse() does not modify by reference. array_reverse()不通过引用修改。 You are confusing the behavior of sort() ing functions.您混淆了sort() ing 函数的行为。 Instead, you merely need to use the returned value that it generates.相反,您只需要使用它生成的返回值。 That said, there is a better way.也就是说,有一个更好的方法。 Read on...继续阅读...

Since PHP5.4, rsort($array, SORT_NATURAL) will sort your array in DESC order and treat consecutive numbers as numbers instead of strings.从 PHP5.4 开始, rsort($array, SORT_NATURAL)将按 DESC 顺序对数组进行排序,并将连续数字视为数字而不是字符串。 This is a more direct and concise way technique versus natsort() ing then array_reverse() ing.natsort() ing 然后array_reverse() ing相比,这是一种更直接和简洁的方式技术。

( Demo ) 演示
( Demo with .jpg extensions ) 带有.jpg扩展名的演示
( Demo with static string before numbers ) 数字前带有静态字符串的演示

I recommend using glob() to scan your directory.我建议使用glob()来扫描您的目录。 This way you can add the .png filter in the same call.这样您就可以在同一个调用中添加.png过滤器。

$dir = 'dead_dir/dead_content/';
$filepaths = glob($dir . '*.png');
rsort($filepaths, SORT_NATURAL);
foreach ($filepaths as $filepath) {
    echo '<img src="' . $filepath . '" />';
}

If you would rather omit the path and just return the filenames, just change your c urrent w orking d irectory.如果你宁愿忽略的路径,并只返回文件名,只是改变你的C urrent w ^ d工作会有irectory。

chdir('dead_dir/dead_content');
$filenames = glob('*.png');
rsort($filenames, SORT_NATURAL);
foreach ($filenames as $filename) {
    echo "<div>.png filename => $filename</div>";
}

Now, if you require more specialized handling of the filenames, then a custom sorting function may serve you well.现在,如果您需要对文件名进行更专业的处理,那么自定义排序功能可能会很好地为您服务。

As demonstrated in the following snippet, the spaceship operator will auto-magically type juggle digital strings as integers and give the same result as the rsort() solution above.如以下代码段所示,飞船操作员会自动神奇地将rsort()数字字符串输入为整数,并给出与上述rsort()解决方案相同的结果。 Using the spaceship operator is still more direct than using natsort() then array_reverse() .使用飞船运营商仍比使用更直接的natsort()然后array_reverse()

Code: ( Demo )代码:(演示

$filenames = ["10", "1", "100", "1000", "20", "200", "2"];
usort($filenames, function($a, $b) {
    return $b <=> $a;
});

var_export($filenames);

Output:输出:

array (
  0 => '1000',
  1 => '200',
  2 => '100',
  3 => '20',
  4 => '10',
  5 => '2',
  6 => '1',
)

If your filenames have leading or trailing non-numeric characters, you can perform the necessary manipulations to strip the unwanted characters while comparing inside of usort() .如果您的文件名包含前导或尾随非数字字符,您可以在usort()内部进行比较时执行必要的操作以去除不需要的字符。

If anyone is not familiar with how custom sorting works with the spaceship operator...如果有人不熟悉自定义排序如何与飞船操作员一起工作......

  • To achieve ASC order, write $a <=> $b .要实现 ASC 顺序,请编写$a <=> $b
  • To achieve DESC order, write $b <=> $a .要实现 DESC 命令,请编写$b <=> $a
 $dir='dead_dir/dead_content/';
 $launcher= scandir($dir);
 natsort($launcher);
 $r_launcher = array_reverse($launcher,true);

 foreach($r_launcher as $value ){
   if(in_array(pathinfo($value, PATHINFO_EXTENSION),array('png'))){
       echo '<img src="dead_dir/dead_content/'.$value.'" />'}}

If your image names will be in the format 123-image_name.jpg , 2323-image_name.jpg , ... this will do:如果您的图像名称的格式为123-image_name.jpg2323-image_name.jpg ,...这将执行以下操作:

/**
 * Compares digits in image names in the format "123-image_name.jpg"
 *
 * @param string $img1 First image name
 * @param string $img2 Second image name
 * @return integer -1 If first image name digit is greater than second one.
 * 0 If image name digits are equal.
 * 1 If first image name digit is smaller than second one.
 */
function compareImageNames($img1, $img2){
    $ptr = '/^(\d+)-/'; // pattern

    // let's get the number out of the image names
    if (preg_match($ptr, $img1, $m1) && preg_match($ptr, $img2, $m2)) {
        $first  = (int) $m1[0]; // first match integer
        $second = (int) $m2[0]; // second match integer

        // equal don't change places
        if($first === $second) return 0;

        // if move first down if it is lower than second
        return ($first < $second) ? 1 : -1;
    } else{
        // image names didn't have a digit in them
        // move them to front
        return 1;
    }
}

// sort array
usort($images, 'compareImageNames');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM