[英]PHP hierarchical array - Parents and childs
我将 PHP 和 mySQL 与Idiorm一起使用。 那可能不相关。
我的 PHP 数组
如果需要解决问题,可以更改此数组结构。
array (
33 =>
array (
0 => '27',
1 => '41',
),
27 =>
array (
0 => '64',
1 => '71',
),
0 =>
array (
0 => '28',
1 => '29',
2 => '33',
),
)
我的分层结果
像这样的东西,但作为一个数组......
0 =>
28
29
33
27 =>
64
71
41
信息
我自己的想法
我尝试了以上两种方法,只是弄得一团糟。 这是一个脑筋急转弯。
@deceze 的建议奏效了。 但是输入数组需要稍微改变一下,就像这样......
$rows = array(
array(
'id' => 33,
'parent_id' => 0,
),
array(
'id' => 34,
'parent_id' => 0,
),
array(
'id' => 27,
'parent_id' => 33,
),
array(
'id' => 17,
'parent_id' => 27,
),
);
来自https://stackoverflow.com/a/8587437/476 :
function buildTree(array $elements, $parentId = 0) {
$branch = array();
foreach ($elements as $element) {
if ($element['parent_id'] == $parentId) {
$children = buildTree($elements, $element['id']);
if ($children) {
$element['children'] = $children;
}
$branch[] = $element;
}
}
return $branch;
}
$tree = buildTree($rows);
print_r( $tree );
我在@Jens Törnell 的答案中添加了启用定义 parent_id 的列名、子数组键名以及 id 的列名的选项。
/**
* function buildTree
* @param array $elements
* @param array $options['parent_id_column_name', 'children_key_name', 'id_column_name']
* @param int $parentId
* @return array
*/
function buildTree(array $elements, $options = [
'parent_id_column_name' => 'parent_id',
'children_key_name' => 'children',
'id_column_name' => 'id'], $parentId = 0)
{
$branch = array();
foreach ($elements as $element) {
if ($element[$options['parent_id_column_name']] == $parentId) {
$children = buildTree($elements, $options, $element[$options['id_column_name']]);
if ($children) {
$element[$options['children_key_name']] = $children;
}
$branch[] = $element;
}
}
return $branch;
}
由于功能非常通用,我设法在我的大部分项目中使用了上述功能。
来自@Jens Törnell 的好回答,只是想添加一点改进,如果您的 parent_id 和 id 实际上是字符串而不是数字,那么上述方法将失败,并且在创建子数组后,它将再次创建这些子数组作为单独的单独数组。 为了解决这个问题,您应该进行三重相等检查并通过比较告诉变量的数据类型即(字符串)。
对于数组中基于字符串的 Id 和 Parent_id
function buildTree(array $elements, $parentId = 0) {
$branch = array();
foreach ($elements as $element) {
if ((string)$element['parent_id'] === (string)$parentId) {
$children = buildTree($elements, $element['id']);
if ($children) {
$element['children'] = $children;
}
$branch[] = $element;
}
}
return $branch;
}
此外,如果有人愿意,他还可以向函数添加第三个参数,以动态指定变量的数据类型,即function buildTree(array $elements, $parentId = 0, $datatype='string')
但是你将不得不采取发生任何其他错误。
希望它能帮助别人!
public function createTree (&$list, $parentId = null) {
$tree = array();
foreach ($list as $key => $eachNode) {
if ($eachNode['parentId'] == $parentId) {
$eachNode['children'] = $this->createTree ($list,$eachNode['id']);
$tree[] = $eachNode;
unset($list[$key]);
}
}
return $tree;
}
在该函数中传递关联数组,如果最父级不为空,则只需将最父级 id 作为第二个参数传递。
我有一个不同的问题,在此页面上找不到适合我的解决方案。 我需要创建一棵树,但不知道 root id 。 这意味着我必须遍历我的平面数组并在树的顶部构建具有最多父项目的分支。
如果其他人需要构建没有根父项目 ID 的树,我就是这样做的。
<?php
$rows = [
(object) [
'id' => 1001,
'parentid' => 1000,
'name' => 'test1.1'
],
(object) [
'id' => 1000,
'parentid' => 100,
'name' => 'test1'
],
(object) [
'id' => 1002,
'parentid' => 1000,
'name' => 'test1.2'
],
(object) [
'id' => 1004,
'parentid' => 1001,
'name' => 'test1.1.1'
],
(object) [
'id' => 1005,
'parentid' => 1004,
'name' => 'test1.1.1.1'
],
(object) [
'id' => 100,
'parentid' => 10,
'name' => 'test 0'
],
(object) [
'id' => 1006,
'parentid' => 1002,
'name' => 'test1.2.1'
],
(object) [
'id' => 1007,
'parentid' => 1002,
'name' => 'test1.2.2'
],
];
function add_child(stdClass $parent, stdClass $child) {
if ($child->parentid != $parent->id) {
throw new Exception('Attempting to add child to wrong parent');
}
if (empty($parent->children)) {
$parent->children = [];
} else {
// Deal where already in branch.
foreach ($parent->children as $idx => $chd) {
if ($chd->id === $child->id) {
if (empty($chd->children)) {
// Go with $child, since $chd has no children.
$parent->children[$idx] = $child;
return;
} else {
if (empty($child->children)) {
// Already has this child with children.
// Nothing to do.
return;
} else {
// Both childs have children - merge them.
$chd->children += $child->children;
$parent->children[$idx] = $child;
return;
}
}
}
}
}
$parent->children[] = $child;
}
function build_branch(&$branch, &$rows, &$parent = null) {
$hitbottom = false;
while (!$hitbottom) {
$foundsomething = false;
// Pass 1 - find children.
$removals = []; // Indexes of rows to remove after this loop.
foreach ($rows as $idx => $row) {
if ($row->parentid === $branch->id) {
// Found a child.
$foundsomething = true;
// Recurse - find children of this child.
build_branch($row, $rows, $branch);
add_child($branch, $row);
$removals[] = $idx;
}
}
foreach ($removals as $idx) {
unset($rows[$idx]);
}
// Pass 2 - find parents.
if ($parent === null) {
$foundparent = false;
foreach ($rows as $idx => $row) {
if ($row->id === $branch->parentid) {
// Found parent
$foundsomething = true;
$foundparent = true;
add_child($row, $branch);
unset ($rows[$idx]);
// Now the branch needs to become the parent since parent contains branch.
$branch = $row;
// No need to search for other parents of this branch.
break;
}
}
}
$hitbottom = !$foundsomething;
}
}
function build_tree(array $rows) {
$tree = [];
while (!empty($rows)) {
$row = array_shift($rows);
build_branch($row, $rows);
$tree[] = $row;
}
return $tree;
}
$tree = build_tree($rows);
print_r($tree);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.