我有一个对象列表,这些对象是具有“n”个子对象的其他相同对象的父对象。
为了列出 parent 的名单,我设法这样做了:
echo "<ol>";
foreach ($indicator_dimensions as $dimension) {
if (empty($dimension->parent)) {
echo "<li>";
echo $dimension->dimension;
$subdimensions = Indicator_dimension::find_by_sql("SELECT * FROM indicator_dimension where parent=".$dimension->id);
if (count($subdimensions) != 0) {
find_leaves($subdimensions);
}
echo "</li>";
}
}
echo "</ol>";
要列出他们的 child ,我正在使用这个函数:
function find_leaves($dimensions){
echo "<ol>";
foreach ($dimensions as $dimension) {
echo "<li>";
echo $dimension->dimension;
if (!empty($dimension->parent)) {
$subdimensions = Indicator_dimension::find_by_sql("SELECT * FROM indicator_dimension where parent=".$dimension->id);
if (count($subdimensions) != 0) {
find_leaves($subdimensions);
}
}
echo "</li>";
}
echo "</ol>";
}
虽然它可以工作,但它是丑陋的代码我想重构但还没有头脑......
提前感谢任何增强技巧!
最佳答案
这看起来您需要一个经典的树实现。它由具有 n 个子节点的节点组成。 我写了一个小例子实现 here .我知道遍历不是很干净,但它可以满足您的需求。
我将所有魔法委托(delegate)给了 ListRenderer 的遍历方法。这将递归地挖掘到当前遍历节点的子节点中:
protected function traverse(Node $node) {
if($node->__toString()) $this->output .= '<li>'.$node.'</li>'; //echo current node
if($node->hasChildren()) {
$this->output .= '<ol>';
foreach($node->getChildren() as $child) {
$this->traverse($child); //repeat for children
}
$this->output .= '</ol>';
}
}
请注意根节点不回显<li>root</li>
因为它的标签是空的。所以示例的结果输出将是:
<ol>
<li>sub1</li>
<li>sub2</li>
<ol>
<li>sub a</li>
<li>sub b</li>
<li>sub c</li>
</ol>
<li>sub3</li>
</ol>
这正是您想要的。
如果您想了解有关树遍历的更多信息,请查看 the wikipedia article about tree traversal .
关于php - 递归列表函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21220207/