Sorting an array of directory filenames in descending natural order

前端 未结 3 1417
没有蜡笔的小新
没有蜡笔的小新 2021-01-25 09:06

I have a content directory to be returned in descending natural order.

I\'m using scandir() and natsort(), but the addition of array_reve

相关标签:
3条回答
  • 2021-01-25 09:45

    The problem is simple. array_reverse() does not modify by reference. You are confusing the behavior of sort()ing functions. 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. This is a more direct and concise way technique versus natsort()ing then array_reverse()ing.

    (Demo)
    (Demo with .jpg extensions)
    (Demo with static string before numbers)

    I recommend using glob() to scan your directory. This way you can add the .png filter in the same call.

    $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 current working directory.

    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. Using the spaceship operator is still more direct than using natsort() then 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().

    If anyone is not familiar with how custom sorting works with the spaceship operator...

    • To achieve ASC order, write $a <=> $b.
    • To achieve DESC order, write $b <=> $a.
    0 讨论(0)
  • 2021-01-25 09:46

    If your image names will be in the format 123-image_name.jpg, 2323-image_name.jpg, ... this will do:

    /**
     * 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');
    
    0 讨论(0)
  • 2021-01-25 09:50
     $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.'" />'}}
    
    0 讨论(0)
提交回复
热议问题