像计算机上的文件名一样按键对关联数组进行排序

Sort associative array by key like filenames on a computer

我有以下结构:

$arr = [
    'children' => [
        'align.php' => [],
        'default.php' => [],
        'test.php' => [],
        'default-2.php' => [],
    ]
]

目前我正在使用

ksort($arr['children'])

它是这样排序的:

$arr = [
    'children' => [
        'align.php' => [],
        'default-2.php' => [],
        'default.php' => [],
        'test.php' => [],
    ]
]

但是,我需要数组按以下顺序排列:

$arr = [
    'children' => [
        'align.php' => [],
        'default.php' => [],
        'default-2.php' => [],
        'test.php' => [],
    ]
]

我试过 NATURAL_SORT 标志,但没有用。还有哪些其他选择?

您可以使用 pathinfo function, and then compare them in the callback function in the uksort 函数提取文件名。

uksort($arr['children'], function($a, $b){
    $a = pathinfo($a);
    $b = pathinfo($b);
    return $a['filename'] == $b['filename'] ? 
        $a['basename'] <=> $b['basename'] :
        $a['filename'] <=> $b['filename'];

});

fiddle

一个比较复杂的多点文件名排序解决,比如像这样

/* Example:
    a
    a.class
    a.class.php
    a.class.php-1
    a.class-1.php
    a.class-1.php-1
    a-1
    a-1.class.php
    a-1.class-1
    a-1.class-1.php-1
*/

uksort($arr['children'], function($a, $b){
    $a = explode('.', $a);
    $b = explode('.', $b);
    $s = '';
    $i = 0;
    while (isset($a[$i]) && isset($b[$i]) && $a[$i] == $b[$i]) {
        $s .= $a[$i++] . '.'; 
    }
    return $s . ($a[$i] ?? '') <=> $s . ($b[$i] ?? '');
});

fiddle