我被一个逻辑卡住了,我不明白它是如何完成的,并遍历列表。
事实上,我正在创建一个类别列表,将进一步用于创建产品。我希望类别列表应该是在父节点的形式,它的子节点像邻接列表模型。
数据库:
id categoryname parent [id is the foreign key for the parent]
1 a 1
2 b 2
3 c 2
4 e 2
5 f 3
6 g 4
在yii 2中使用ActiveQuery获取详细信息:
$rows = Category::find()
->asArray()
->all();
$rows
数组包含的数据如下所示
Array
(
[0] => Array
(
[id] => 1
[categoryname] => a
[parent] => 1
)
[1] => Array
(
[id] => 2
[categoryname] => b
[parent] =>2
)
[2] => Array
(
[id] => 3
[categoryname] => c
[parent] => 2
)
)
And so on...
我想要的输出应该是这样的列表形式
[
[
'id' => 1,
'categoryname' => 'a'
],
[
'id' => 2,
'categoryname' => 'b'
],
[
'id' => 3,
'categoryname' => 'b > c'
],
[
'id' => 4,
'categoryname' => 'b>c>f'
]
]
我尝试过:当我从表中获取行并将它们存储在一个关联数组中时,每个分支节点的child-id都存储在另一个关联数组中。
foreach ($rows as $row){
$id = $row["id"];
$parent_id = $row["parent"] === NULL ? "NULL" : $row["parent"];
$data[$id] = $row;
$index[$parent_id][] = $id;
}
function display_child_nodes($parent_id, $level,$data,$index)
{
$parent_id = $parent_id === NULL ? "NULL" : $parent_id;
if (isset($index[$parent_id])) {
foreach ($index[$parent_id] as $id) {
$result['id'] = $data[$id]['id'];
$result['name'] = $data[$id]['categoryname'];
$result['level'] = $level;
echo str_repeat("-", $level) . $data[$id]["categoryname"] . "\n";
display_child_nodes($id, $level + 1,$data,$index);
}
}
}
display_child_nodes(NULL, 0,$data,$index);
我按照这个reference的结果,但我不能得到所需的输出。
我已经经历了堆栈溢出问题,但没有一个对我有用。所以任何人都可以帮助先进的赞赏。
1条答案
按热度按时间nbnkbykc1#
我们可以使用Iterators来实现这个目的,让我们扩展
RecursiveArrayIterator
并调用新的迭代器AdjacencyListIterator
:顺便说一句,注意,对于顶级父项,
parent
应该是null
(与id
不同)。有了这个迭代器,你可以生成如下路径:
这里是working demo。
这种方法可能比自定义递归函数慢一点,但实际上它更灵活。通过只改变遍历模式,你可以只得到叶子,例如:
这种情况与前面的不同之处在于,我们将
RecursiveIteratorIterator
的$mode
设置为默认值RecursiveIteratorIterator::LEAVES_ONLY
。