
本教程详细介绍了如何将包含父子关系信息的扁平化数组数据,转换为具有层级结构的嵌套数组。通过构建索引和迭代分配子元素,文章提供了一个通用的php解决方案,适用于处理如问答、评论树等多种场景,确保数据结构清晰、易于访问和管理。
在许多应用场景中,我们经常需要处理来自数据库或其他数据源的扁平化数据集,这些数据行之间存在着内在的父子关系。例如,一个问答系统可能包含问题和答案,其中答案关联到特定的问题;一个评论系统则可能包含多级回复。将这种扁平数据转换为嵌套的、具有层级结构的数组,不仅能更好地反映数据间的真实关系,也便于前端展示和业务逻辑处理。
假设我们有一个包含“问题”和“答案”的数组,每个元素都有一个唯一的 PARTY_ID 和一个 PARENT_USER_CONTENT_ID,后者指向其父元素的 PARTY_ID。如果 PARENT_USER_CONTENT_ID 为空,则表示该元素是一个顶级元素(例如,一个问题)。
原始扁平数据示例:
$flatData = [
[ 'TYPE' => 'Question', 'PARTY_ID' => 112, 'PARENT_USER_CONTENT_ID' => '' ],
[ 'TYPE' => 'Answer', 'PARTY_ID' => 115, 'PARENT_USER_CONTENT_ID' => 112 ],
[ 'TYPE' => 'Question', 'PARTY_ID' => 113, 'PARENT_USER_CONTENT_ID' => '' ],
[ 'TYPE' => 'Answer', 'PARTY_ID' => 116, 'PARENT_USER_CONTENT_ID' => 113 ],
[ 'TYPE' => 'Answer', 'PARTY_ID' => 117, 'PARENT_USER_CONTENT_ID' => 112 ], // 112有两个答案
[ 'TYPE' => 'Comment', 'PARTY_ID' => 118, 'PARENT_USER_CONTENT_ID' => 117 ], // 答案下的评论
];期望的层级结构示例:
立即学习“PHP免费学习笔记(深入)”;
[
[
'TYPE' => 'Question',
'PARTY_ID' => 112,
'PARENT_USER_CONTENT_ID' => '',
'children' => [
[
'TYPE' => 'Answer',
'PARTY_ID' => 115,
'PARENT_USER_CONTENT_ID' => 112,
'children' => [] // 或者没有此键
],
[
'TYPE' => 'Answer',
'PARTY_ID' => 117,
'PARENT_USER_CONTENT_ID' => 112,
'children' => [
[
'TYPE' => 'Comment',
'PARTY_ID' => 118,
'PARENT_USER_CONTENT_ID' => 117,
'children' => []
]
]
]
]
],
[
'TYPE' => 'Question',
'PARTY_ID' => 113,
'PARENT_USER_CONTENT_ID' => '',
'children' => [
[
'TYPE' => 'Answer',
'PARTY_ID' => 116,
'PARENT_USER_CONTENT_ID' => 113,
'children' => []
]
]
]
]构建这种层级结构的核心思想是:首先创建一个所有元素的快速查找索引,然后遍历这些元素,将子元素归属到它们的父元素下,并最终收集所有顶级元素。这种方法能够处理任意深度的嵌套关系。
首先,我们需要遍历原始的扁平数据,为每个元素创建一个以其 PARTY_ID 为键的索引,以便能快速通过ID查找任何元素。同时,为每个元素预留一个 children 数组,用于存放其子元素。
$tree = []; // 最终的层级结构数组,存放所有顶级元素
$indexedItems = []; // 临时索引,用于通过ID快速查找元素
// 第一次遍历:索引所有元素并初始化 'children' 数组
foreach ($flatData as &$item) {
$item['children'] = []; // 为每个元素添加一个空的 'children' 数组
$indexedItems[$item['PARTY_ID']] = &$item; // 使用引用存储,以便后续修改能反映到原始数据
}
unset($item); // 解除最后一次循环的引用,避免意外修改说明:
接下来,我们再次遍历索引后的元素。对于每个元素,如果它有 PARENT_USER_CONTENT_ID 且其父元素存在于 $indexedItems 中,就将当前元素添加到其父元素的 children 数组中。如果一个元素没有 PARENT_USER_CONTENT_ID,则它是一个顶级元素,应将其添加到最终的 $tree 数组中。
// 第二次遍历:构建层级关系
foreach ($indexedItems as $id => &$item) {
$parentId = $item['PARENT_USER_CONTENT_ID'];
// 检查是否存在父ID且父元素在索引中
if (!empty($parentId) && isset($indexedItems[$parentId])) {
// 将当前元素添加到其父元素的 'children' 数组中
$indexedItems[$parentId]['children'][] = &$item;
} else {
// 如果没有父ID,则它是一个顶级元素,添加到最终的 $tree 数组中
$tree[] = &$item;
}
}
unset($item); // 解除最后一次循环的引用说明:
将以上两个步骤结合起来,形成一个完整的函数或代码块:
<?php
$flatData = [
[ 'TYPE' => 'Question', 'PARTY_ID' => 112, 'PARENT_USER_CONTENT_ID' => '' ],
[ 'TYPE' => 'Answer', 'PARTY_ID' => 115, 'PARENT_USER_CONTENT_ID' => 112 ],
[ 'TYPE' => 'Question', 'PARTY_ID' => 113, 'PARENT_USER_CONTENT_ID' => '' ],
[ 'TYPE' => 'Answer', 'PARTY_ID' => 116, 'PARENT_USER_CONTENT_ID' => 113 ],
[ 'TYPE' => 'Answer', 'PARTY_ID' => 117, 'PARENT_USER_CONTENT_ID' => 112 ],
[ 'TYPE' => 'Comment', 'PARTY_ID' => 118, 'PARENT_USER_CONTENT_ID' => 117 ],
[ 'TYPE' => 'Comment', 'PARTY_ID' => 119, 'PARENT_USER_CONTENT_ID' => 117 ],
[ 'TYPE' => 'Question', 'PARTY_ID' => 120, 'PARENT_USER_CONTENT_ID' => '' ],
];
function buildHierarchy(array $flatData, string $idKey = 'PARTY_ID', string $parentKey = 'PARENT_USER_CONTENT_ID', string $childrenKey = 'children'): array
{
$tree = [];
$indexedItems = [];
// 第一次遍历:索引所有元素并初始化 'children' 数组
foreach ($flatData as &$item) {
$item[$childrenKey] = [];
$indexedItems[$item[$idKey]] = &$item;
}
unset($item); // 解除引用
// 第二次遍历:构建层级关系
foreach ($indexedItems as $id => &$item) {
$parentId = $item[$parentKey];
if (!empty($parentId) && isset($indexedItems[$parentId])) {
$indexedItems[$parentId][$childrenKey][] = &$item;
} else {
$tree[] = &$item;
}
}
unset($item); // 解除引用
return $tree;
}
$hierarchicalData = buildHierarchy($flatData);
echo '<pre>';
print_r($hierarchicalData);
echo '</pre>';
?>以上就是将扁平数据转换为分层结构:PHP数组操作教程的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号