繁体   English   中英

递归排序多维数组的键

[英]Recursively sort keys of a multidimensional array

我很难尝试对多维数组的键进行递归排序。 我尝试使用usort() ,但没有成功。

样本数据:

[
    'first_level' => [
        'dir_3' => [
            'subdir_1' => [
                'file_2.mp4' => (object) [
                    'name' => 'file_2.mp4',
                ],
                'file_1.mp4' => (object) [
                    'name' => 'file_1.mp4',
                ],
            ],
        ],
        'dir_1' => [
            'subdir_2' => [
                'file_6.mp4' => (object) [
                    'name' => 'file_6.mp4',
                ],
                'file_9.mp4' => (object) [
                    'name' => 'file_9.mp4',
                ],
                'file_7.mp4' => (object) [
                    'name' => 'file_7.mp4',
                ],
            ],
            'subdir_1' => [
                'file_8.mp4' => (object) [
                    'name' => 'file_8.mp4',
                ],
            ],
        ],
    ],
]

期望的结果:

[
    'first_level' => [
        'dir_1' => [
            'subdir_1' => [
                'file_8.mp4' => (object) [
                    'name' => 'file_8.mp4',
                ],
            ],
            'subdir_2' => [
                'file_6.mp4' => (object) [
                    'name' => 'file_6.mp4',
                ],
                'file_7.mp4' => (object) [
                    'name' => 'file_7.mp4',
                ],
                'file_9.mp4' => (object) [
                    'name' => 'file_9.mp4',
                ],
            ],
        ],
        'dir_3' => [
            'subdir_1' => [
                'file_1.mp4' => (object) [
                    'name' => 'file_1.mp4',
                ],
                'file_2.mp4' => (object) [
                    'name' => 'file_2.mp4',
                ],
            ],
        ],
    ],
]

使用递归函数:

// Note this method returns a boolean and not the array
function recur_ksort(&$array) {
   foreach ($array as &$value) {
      if (is_array($value)) recur_ksort($value);
   }
   return ksort($array);
}

您需要使用ksort

// Not tested ...    
function recursive_ksort(&$array) {
    foreach ($array as $k => &$v) {
        if (is_array($v)) {
            recursive_ksort($v);
        }
    }
    return ksort($array);
}
function ksort_recursive(&$array)
{
    if (is_array($array)) {
        ksort($array);
        array_walk($array, 'ksort_recursive');
    }
}

如他们的评论所述, return ksort()的答案不正确,因为 ksort() 返回成功布尔值。

请注意,当给定一个非数组时,此函数不会抛出“警告:ksort() 期望参数 1 为数组”——这符合我的要求,但可能不符合你的要求。

可以公平地假设您希望您的数据“自然地”排序——这意味着目录和文件名的数字部分应该按数字而不是简单的字符串排序。 如果不自然排序, dir_10会移到dir_2前面,因为比较两个字符串的第 5 个字符时,1 小于 2。

代码:(演示

function nat_ksort_r(&$data): void
{
    if (is_array($data)) {
        ksort($data, SORT_NATURAL);
        array_walk($data, __METHOD__);
    }
}

nat_ksort_r($array);
var_export($array);
  • 对于自然排序,将SORT_NATURAL标志应用于 ksort ksort()调用。
  • 为了更简单地维护递归 function,请使用__METHOD__魔法常量调用 function。 如果您希望将自定义 function 称为其他内容,这将减少更改nat_ksort_r()的地方。
  • 这个递归function不返回任何数据; 它通过引用修改原始数组。
  • 最低级别包含对象,此数据未按 function 排序。

上面的 function 也可以使用经典循环代替函数式迭代器。 演示

function nat_ksort_r(&$data): void
{
    if (is_array($data)) {
        ksort($data, SORT_NATURAL);
        foreach ($data as &$item) {
            (__METHOD__)($item);
        }
    }
}

nat_ksort_r($array);
var_export($array);

您甚至可以以完全匿名的方式编写代码。 演示

$nat_ksort_r = function(&$data) use (&$nat_ksort_r) {
    if (is_array($data)) {
        ksort($data, SORT_NATURAL);
        foreach ($data as &$item) {
            $nat_ksort_r($item);
        }
    }
};
$nat_ksort_r($array);
var_export($array);

暂无
暂无

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

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