You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

递归排序未知深度多维数组的position列并保留键

递归按position排序多维数组问题

问题说明

需要递归对多维数组的每一层级(存在children节点时)按position字段排序,数组结构可变,children节点可能存在或不存在。尝试使用usort未得到预期结果,且因结构限制无法使用嵌套集方案。

原数组

[
    2 => [
        'position' => 0,
        'children' => [
            3 => ['position' => "375"],
            5 => ['position' => "44"],
            6 => ['position' => "567"],
            9 => [
                'position' =>  "12",
                'children' => [
                    74 => ['position' => "2"],
                    76 => ['position' => "3"],
                    77 => ['position' => "1"],
                ]
            ],
            62 => ['position' => "34"],
            63 => ['position' => "11"],
            66 => ['position' => "114"],
            74 => ['position' => "912"],
            76 => ['position' => "4564"],
        ]
    ]
]

期望排序结果

[
    2 => [
        'position' => 0,
        'children' => [
            63 => ['position' => "11"],
            9 => [
                'position' =>  "12",
                'children' => [
                    77 => ['position' => "1"],
                    74 => ['position' => "2"],
                    76 => ['position' => "3"],
                ]
            ],
            62 => ['position' => "34"],
            5 => ['position' => "44"],
            66 => ['position' => "114"],
            3 => ['position' => "375"],
            6 => ['position' => "567"],
            74 => ['position' => "912"],
            76 => ['position' => "4564"],
        ]
    ]
]

尝试的错误代码

public function recur($data){
    // ...
    foreach($data as $key=>$value){
        if (array_key_exists('children', $value)) {
            usort($value, function ($a, $b): int {
                if ($a['position'] === $b['position']) {
                // ....
                }
                return $a['position'] <=> $b['position'];
            });
        }
    }
}

问题分析与解决方案

错误代码存在三个核心问题:

  1. usort不保留关联键名:children是带自定义键的关联数组,usort会重置为索引数组,应该用uasort保留原键。
  2. 未递归处理子节点:只排序了当前层级的children,但children内的元素如果还有自己的children,没有继续递归处理。
  3. 字符串比较逻辑问题:position字段是字符串类型,直接用太空船运算符会按字符串排序(比如"2"和"11"字符串排序会出错),需转为整数比较。
  4. 值传递未修改原数组:遍历中用$value是值拷贝,修改后不会同步到原数组,需用引用或重新赋值。

正确的递归排序函数

public function sortByPositionRecursive(&$data)
{
    foreach ($data as &$item) {
        // 如果当前元素有children,先排序children
        if (isset($item['children']) && is_array($item['children'])) {
            // 用uasort保留原键名,按position整数排序
            uasort($item['children'], function($a, $b) {
                return (int)$a['position'] <=> (int)$b['position'];
            });
            // 递归处理children里的每个子元素
            $this->sortByPositionRecursive($item['children']);
        }
    }
    // 释放引用避免后续问题
    unset($item);
}

使用示例

// 原数组
$originalArray = [
    2 => [
        'position' => 0,
        'children' => [
            3 => ['position' => "375"],
            5 => ['position' => "44"],
            6 => ['position' => "567"],
            9 => [
                'position' =>  "12",
                'children' => [
                    74 => ['position' => "2"],
                    76 => ['position' => "3"],
                    77 => ['position' => "1"],
                ]
            ],
            62 => ['position' => "34"],
            63 => ['position' => "11"],
            66 => ['position' => "114"],
            74 => ['position' => "912"],
            76 => ['position' => "4564"],
        ]
    ]
];

// 调用排序函数
$this->sortByPositionRecursive($originalArray);

// 输出结果即为期望的排序后数组
print_r($originalArray);

说明

  • 函数参数使用引用传递&$data,确保直接修改原数组,无需返回值。
  • uasort保证排序后保留原数组的键名(比如63、9这些自定义键)。
  • 将position转为整数比较,避免字符串排序的逻辑错误。
  • 递归调用处理每个层级的children,实现全层级排序。

内容的提问来源于stack exchange,提问作者TheTom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 13:55:14