[英]Build unordered list from multidimensional array without recursion
我在從包含實體及其子級的多維數組中構建無序列表時遇到問題。 問題是我不想使用遞歸,因為樹可能變得很深,遞歸可能在服務器上產生不必要的負載。
這是此類數組的一個示例(簡化為僅包含title
和children
,並且實體也可以是對象)。
$array = array(
array('title' => '1', 'children' => array()),
array('title' => '2', 'children' => array()),
array('title' => '3', 'children' => array()),
array('title' => '4', 'children' => array(
array('title' => '41', 'children' => array()),
array('title' => '42', 'children' => array()),
array('title' => '43', 'children' => array()),
array('title' => '44', 'children' => array(
array('title' => '441', 'children' => array()),
array('title' => '442', 'children' => array()),
array('title' => '443', 'children' => array()),
array('title' => '444', 'children' => array(
array('title' => '4441', 'children' => array()),
array('title' => '4442', 'children' => array()),
array('title' => '4443', 'children' => array())
)),
)),
array('title' => '45', 'children' => array())
)),
array('title' => '5', 'children' => array()),
array('title' => '6', 'children' => array(
array('title' => '61', 'children' => array()),
array('title' => '62', 'children' => array()),
array('title' => '63', 'children' => array())
)),
array('title' => '7', 'children' => array())
);
在SO上做一些研究,我想到了這個解決方案,它非常接近我想要的解決方案:
<html>
<head></head>
<body>
<ul>
<?php
$stack = $array;
$i = 0;
$counts = array();
while(!empty($stack)) {
$node = array_shift($stack);
echo "<li>{$node['title']}";
if($node['children']) {
echo "<ul>";
$counts[] = count($node['children']);
$node['children'] = array_reverse($node['children']);
foreach($node['children'] as $ch)
array_unshift($stack, $ch);
}
if(!empty($counts)) {
end($counts);
if($counts[$key] == 0) {
echo "</ul>";
array_pop($counts);
} else {
$counts[$key]--;
}
}
if(!$node['children']) {
echo "</li>";
}
// just to make sure we won't end in infinite loop
$i++;
if($i == 50) break;
}
?>
</ul>
</body>
</html>
輸出在下面-如您所見,我</ul>
的問題只是子樹的結束</ul>
。 我的問題 :我是否想得太多,還是盲目看不到明顯的錯誤? 您能否將我推向有限解決方案,還是給我您自己的解決方案?
輸出:
這不是代碼的修復程序,但無論如何它可能會幫助您:
function helper($input) {
$input[] = '</ul>';
$input = array_reverse($input);
$input[] = '<ul>';
// output
while (sizeof($input) > 0) {
$el = array_pop($input);
if (!is_array($el)) {
echo $el;
}
else {
// add current element
$input[] = sprintf('<li>%s', $el['title']);
// add children
if (sizeof($el['children']) > 0) {
$input[] = '</ul>';
$input = array_merge($input, array_reverse($el['children']));
$input[] = '<ul>';
}
// add closing li
$input[] = '</li>';
}
}
}
helper($array);
好吧,通常情況下- ask for a solution You are solving for hours and immediately You are out with one...
因此,經過一小段放松之后,我又想了些什么,想出了以下解決方案:
<html>
<head></head>
<body>
<ul>
<?php
$i = 0;
$counts = array();
while(!empty($stack)) {
$node = array_shift($stack);
if(!empty($counts)) {
while(end($counts) === 0) {
$key = key($counts);
echo "</li></ul>";
array_pop($counts);
}
end($counts);
$key = key($counts);
if(isset($counts[$key])) {
$counts[$key]--;
}
}
echo "<li>{$node['title']}";
if($node['children']) {
echo "<ul>";
$counts[] = count($node['children']);
$node['children'] = array_reverse($node['children']);
foreach($node['children'] as $ch)
array_unshift($stack, $ch);
}
if(!$node['children']) {
echo "</li>";
}
$i++;
if($i == 50) break;
}
?>
</ul>
<p>$i = <?php echo $i; ?></p>
</body>
</html>
問題是我錯過了另一個, while
這應該一直減去$counts
值一直備份到樹上。
我將等待接受我自己的答案,以防有人發布他們應該接受的更好的解決方案,而不是我提出的不是那么整潔的解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.