关于树形数据反向排序组树的问题

现有数据如下:

$data = [
    [
        'id' => 1,
        'name' => '爷爷',
        'fid' => 0,
    ],
    [
        'id' => 11,
        'name' => '爸爸',
        'fid' => 1,
    ],
    [
        'id' => 111,
        'name' => '儿子',
        'fid' => 11,
    ],
];

我们常见的数据结构排序是这样的:

$tree = [
    'id' => 1,
    'name' => '爷爷',
    'fid' => 0,
    'child' => [
        'id' => 11,
        'name' => '爸爸',
        'fid' => 1,
        'child' => [
            'id' => 111,
            'name' => '儿子',
            'fid' => 11,
        ]
    ]
];

现在我想实现反向的排序, 数据结构如下:

$tree = [
    'id' => 111,
    'name' => '儿子',
    'fid' => 11,
    'child' => [
        'id' => 11,
        'name' => '爸爸',
        'fid' => 1,
        'child' => [
            'id' => 1,
            'name' => '爷爷',
            'fid' => 0,
        ]
    ]
];

想问一下大家有什么优雅的排序方式实现过程

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
最佳答案

如果是我会这么写,但可能距离你说的优雅还有差距

function tree(array $data): array
{
    $tree=[];
    $fidAggregate=array_column($data,'fid');
    $childList=array_fill_keys($fidAggregate,[]);
    while ($item = array_shift($data)){
        $item['child']=&$childList[$item['fid']];
        if(in_array($item['id'],$fidAggregate)){
            $childList[$item['id']][]=$item;
        }else{
            $tree[]=$item;
        }
    }
    return $tree;
}
3年前 评论
讨论数量: 6

如果是这样:

$data = [
    [
        'id' => 1,
        'name' => '爷爷',
        'fid' => 0,
    ],
    [
        'id' => 11,
        'name' => '爸爸',
        'fid' => 1,
    ],
    [
        'id' => 111,
        'name' => '儿子',
        'fid' => 11,
    ],
    [
        'id' => 22,
        'name' => '叔叔',
        'fid' => 1,
    ],
    [
        'id' => 222,
        'name' => '堂弟',
        'fid' => 22,
    ],
    [
        'id' => 3,
        'name' => '外公',
        'fid' => 0,
    ],
    [
        'id' => 33,
        'name' => '舅舅',
        'fid' => 3,
    ],
];

那你要的排序结果是这样?

$tree =[
     [
    'id' => 111,
    'name' => '儿子',
    'fid' => 11,
    'child' => [
        'id' => 11,
        'name' => '爸爸',
        'fid' => 1,
        'child' => [
            'id' => 1,
            'name' => '爷爷',
            'fid' => 0,
        ]
    ]
], [
    'id' => 222,
    'name' => '堂弟',
    'fid' => 22,
    'child' => [
        'id' => 22,
        'name' => '叔叔',
        'fid' => 1,
        'child' => [
            'id' => 1,
            'name' => '爷爷',
            'fid' => 0,
        ]
    ]
], [
    'id' => 33,
    'name' => '舅舅',
    'fid' => 3,
    'child' => [
        'id' => 3,
        'name' => '外公',
        'fid' => 0,
    ]
]
];

这样的话儿子,堂弟,舅舅岂不是在同一级了?

3年前 评论
小学毕业生 (楼主) 3年前
renxiaotu (作者) 3年前
pi_phq 3年前

如果是我会这么写,但可能距离你说的优雅还有差距

function tree(array $data): array
{
    $tree=[];
    $fidAggregate=array_column($data,'fid');
    $childList=array_fill_keys($fidAggregate,[]);
    while ($item = array_shift($data)){
        $item['child']=&$childList[$item['fid']];
        if(in_array($item['id'],$fidAggregate)){
            $childList[$item['id']][]=$item;
        }else{
            $tree[]=$item;
        }
    }
    return $tree;
}
3年前 评论

fid 看成之前的 id , id 看成之前的 fid

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!