【问题标题】:How to create an array from this result set (nested categories stored in databased with traversal model)?如何从此结果集中创建一个数组(使用遍历模型存储在数据库中的嵌套类别)?
【发布时间】:2011-04-09 18:46:28
【问题描述】:

基于这个问题: Getting a modified preorder tree traversal model (nested set) into a <ul>

下面的逻辑是用来构建有序列表的,但是如何对数组做同样的事情呢?

我想构建一个嵌套数组。

// bootstrap loop
$result = '';
$currDepth = -1;  // -1 to get the outer <ul>
while (!empty($tree)) {
  $currNode = array_shift($tree);
  // Level down?
  if ($currNode['depth'] > $currDepth) {
    // Yes, open <ul>
    $result .= '<ul>';
  }
  // Level up?
  if ($currNode['depth'] < $currDepth) {
    // Yes, close n open <ul>
    $result .= str_repeat('</ul>', $currDepth - $currNode['depth']);
  }
  // Always add node
  $result .= '<li>' . $currNode['title'] . '</li>';
  // Adjust current depth
  $currDepth = $currNode['depth'];
  // Are we finished?
  if (empty($tree)) {
    // Yes, close n open <ul>
    $result .= str_repeat('</ul>', $currDepth + 1);
  }
}

print $result;

【问题讨论】:

    标签: php sql mysql arrays tree-traversal


    【解决方案1】:

    啊,终于有可以参考的东西了:

    <?php
    $tree = array(
        array('Cat 1', 'depth' => 0),
        array('Cat 2', 'depth' => 1),
        array('Cat 3', 'depth' => 1),
        array('Cat 4', 'depth' => 2),
        array('Cat 5', 'depth' => 1),
        array('Cat 6', 'depth' => 2),
        array('Cat 7', 'depth' => 3),
        array('Cat 8', 'depth' => 1)
    );
    //same as before
    $currDepth = -1;
    
    //initilialize result
    $result = array();
    
    //create path structure for depths
    $path = array();
    
    //create 'root' node
    $olditem = array('children'=> &$result);
    
    
    foreach($tree as $item){
        if($item['depth'] > $currDepth){
            //remove possible old reference (old depth of other branch
            if(isset($path[$item['depth']])) unset($path[$item['depth']]);
    
            //make sure we have an array entry
            if(!isset($olditem['children'])) $olditem['children'] = array();
    
            //acquire target
            $path[$item['depth']] = &$olditem['children'];
        }
        if($item['depth'] != $currDepth) unset($olditem);
        //set correct target
        $currDepth = $item['depth'];
        //add item
        $path[$currDepth][] = &$item;
        //copy & remove reference
        $olditem = &$item;
        unset($item);
    }
    //always nice to clean up reference bombs:
    unset($path);
    unset($olditem);
    
    var_dump($result);
    ?>
    

    【讨论】:

    • 非常感谢!我已经测试过并且工作正常,现在我正在尝试理解。路径变量上的第一个未设置是否使其在循环外的声明无用? $path = array(0 => array('children'=> &$result)); AND if(isset($path[$item['depth']])) unset($path[$item['depth']]);在第一个循环中,它将被删除。
    • 嗯,你说得对,那个可以去,被我后来编辑的$olditem取代了。稍后我会稍微修改一下答案。
    • 当你取消设置 $olditem 为什么它不会影响 $path[$item['depth']] 因为它是通过引用传递的?我对此感到困惑。似乎这不会影响最终结果,换句话说,如果我更改,参考值会受到影响,但如果我取消设置则不会。
    • 嗯,一步一步的参考解释是相当多的工作,今晚晚些时候我会看看我能做些什么。
    • 这真的很优雅。我仍在努力思考它是如何工作的。愿意提供演练吗?
    猜你喜欢
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-06
    相关资源
    最近更新 更多