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

现有数据如下:

$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,
        ]
    ]
];

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

《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
最佳答案

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

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;
}
2年前 评论
讨论数量: 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,
    ]
]
];

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

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

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

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;
}
2年前 评论

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

2年前 评论

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