【问题标题】:Generating a tree from nested set从嵌套集生成树
【发布时间】:2018-01-24 02:35:51
【问题描述】:

我希望从嵌套的集合数据中显示一个 html 树。

由于显示的树并不总是显示所有分支,因此无法通过减去 lft 和 rgt 值来识别叶节点。

              1 Drinks 27
           /       |       \
 2 Coffee 3     4 Tea 20     21 Milk 26
               /        \
         5 Black 8     9 Green 19
                       /       \
             10 China 14      15 Africa 18

我希望修改以下代码: How to render all records from a nested set into a real html tree

解决方案:

很高兴收到代码改进建议:)

def tree_from_set(set, start_level)
  buf = "<ul>"
  parent = []
  prev = set[start_level]
  set[start_level+1..-1].each do |node|

    if node.lft.between?(prev.lft, prev.rgt)
      # Previous was the parent
      buf << open_parent_tag(prev)
      parent.push(prev)
    else
      if node.lft.between?(parent.last.lft, parent.last.rgt)
        #Previous was a child
        buf << leaf_tag(prev)
      else
        buf << leaf_tag(prev)
        begin
          buf << "</ul></li>"
          parent.pop
        end until parent.empty? or node.lft.between?(parent.last.lft, parent.last.rgt)
      end
    end  

    prev = node
  end

  buf << leaf_tag(prev)
  begin
    buf << "</ul></li>"
    parent.pop
  end until parent.empty?

  buf << "</ul>"
  buf.html_safe
end


def open_parent_tag(node)
  %{ <li>
       #{link_to(node.name, node)}
       <ul>
  }
end


def leaf_tag(node)
  content_tag(:li, link_to(node.name, node))
end

【问题讨论】:

标签: ruby-on-rails nested-sets


【解决方案1】:

我使用了这个函数,但是在 php 上,而不是在 ruby​​ 上:

<?php
//nested sets data ordered by left
$data = array(
 array("left" => 1, "right" => 10, "name" => "P0"),
 array("left" => 2, "right" => 7, "name" => "P1"),
 array("left" => 3, "right" => 4, "name" => "P11"),
 array("left" => 5, "right" => 6, "name" => "P12"),
 array("left" => 8, "right" => 9, "name" => "P2")
);

//Converter function gets nested sets array and returns nested php array
function nest($arrData){
 $stack = array();
 $arraySet = array();
 foreach( $arrData as $intKey=>$arrValues) {
  $stackSize = count($stack);
  while($stackSize > 0 && $stack[$stackSize-1]['right'] < $arrValues['left']) {
   array_pop($stack);
   $stackSize--;
  }

  $link =& $arraySet;
  for($i=0;$i<$stackSize;$i++) {
   $link =& $link[$stack[$i]['id']]["children"]; //navigate to the proper children array
  }

  $tmp = array_push($link,  array ('item'=>$arrValues,'children'=>array()));
  array_push($stack, array('id' => $tmp-1, 'right' => $arrValues['right']));
 }

 return $arraySet;
}


//Print result
printArray(nest($data));

function printArray($array){
 echo "<ul>";
 foreach ($array as $row){
  $children = $row['children'];
  echo "<li>";
  echo $row['item']['name'];
  if (!empty($children)) printArray($children);
  echo "</li>";
 }
 echo "</ul>";
}
?>

【讨论】:

    【解决方案2】:

    设法将它转换为 C++ 供那些像我一样寻找它的人使用。

    readDataBaseData(QVector<NodeData> &data, DBNode *node)
    {
        if(data.size() < 1){
            return;
        }
    
        QVector<QPair<NodeData, int>> stack;
        DBNode* arrayRes = node;
    
        foreach (NodeData curArrDataItem, data) {
            int stackSize = stack.size();
    
            while(stackSize > 0 &&
                  stack.at(stackSize - 1).first.right < curArrDataItem.left){
    
                stack.pop_back();
                stackSize--;
            }
    
            DBNode* link = arrayRes;
            for(int i = 0; i < stackSize; i++){
                link = link->childAt(stack.at(i).second);
            }
    
            link = new DBNode(curArrDataItem, link);
            stack.push_back(QPair<NodeData, int>(curArrDataItem, link->getParent()->childCount() - 1));
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-14
      相关资源
      最近更新 更多