2016-11-17 18:22 阅读 39

递归 - 如何构造没有id的数据树,数据是模糊的。

Please refer to the solution, this has been solved.

I have the following dataset and no ids are provided, trying to get this completed using recursion.

Should I attempt this or should I go another route? Because there are no ids.

After a filter on each attribute the root is gender, node 1 is category and end node is label. I have tried to use array_merge_recursive, array_push and I have tried to construct my own recursive pattern but nothing appears to get the pattern I want.

JSON data:



Here is my PHP code for the recursion which is messy:

  function buildSideBar($searchLayers){
            $count = 0;
            foreach($searchLayers[$count] as $root){
                $this->addChildren($sideBarData,$searchLayers,1,$root, $count);
        }catch (Exception $ex){


    function addChildren(&$sideBarData,$layers,$level,$parent,$count){
        if(!empty($layers[$level]) && is_array($layers[$level])){
            foreach($layers[$level] as $child){
                //check if child is a node
                        $count = 0;
                       // $sideBarData = array_merge_recursive($sideBarData, array("root"=>array("child".$level=>$child)));
                        $sideBarData[0][$level] = $child;
                        $sideBarData[][][$level] = $child;
                      //  $this->addChildren($sideBarData,$layers,$level++,$parents);




    function verifyChildBelongsToParent($child,$parent){
        foreach($this->categoryData as $category){

            if(is_array($parent) && sizeof($parent)>1){
                echo 'Child' . $child;
                echo 'PARENTS ';

                if(strcmp($category->getGender(),$parent[0])==0 && strcmp($category->getCategory(),$parent[1])==0)
                    echo 'Add child ' . $child;
                    return true;

                //echo 'check if ' . $parent .' has child ' . $child;
//                    var_dump($parent);
//                    var_dump($child);
                   // echo 'Add Child';
                    return true;

        return false;


Here is the $searchLayers data that I pass in:

    [0] => "MEN",
    [1] => Array(
    [2] =>Array(
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

1条回答 默认 最新

  • 已采纳
    doudou32012 doudou32012 2016-11-18 13:33

    So here's my solution, there maybe a better one, but I attempted 3 different techniques always thinking that this could be scalable.

    I placed the following limitations on the design, the side menu bar can only be 3 levels deep.

    With that I initially sorted the data to find out the grandparent, parent, child which is detailed in the $searchLayers above, but I passed this into as 3 separate arrays ($layer1, $layer2, $layer3) which comply with the parental hierarchy.

    Here is the code, which all starts by calling the top most function function buildSideMenu($layer1,$layer2,$layer3)

    //starts the construction of a side menu and adds each layer of children to the parent
    function buildSideMenu($layer1, $layer2, $layer3){
      $sideMenu = '<ul class="nav nav-stacked">';
      foreach($layer1 as $layer){
          $sideMenu.= '<li><a class="expandable" href="#">'.$layer.'</a></li>';
          //adds children founded to the parent
          $sideMenu .= $this->buildSideMenuChildern($layer,$layer2,$layer3);
      $sideMenu .= '</ul>';
      $this->sideMenu = $sideMenu;
    //builds on children to a side bar that belogn to a parent
    function buildSideMenuChildern($parent,$layer1,$layer2=''){
        $entries ='';
        foreach($layer1 as $layer){
            //deter mines if the child belongs to the parent
                //if this child has it's own childern, process needs to be repeated, else child is an leaf (aka end node)
                    $entries .= '<li><a class="expandable" href="/'.$this->getTag($layer).'">'.$layer.'</a></li>';
                    $entries .= $this->buildSideMenuChildern(array($parent,$layer),$layer2);
                    $entries .= '<li><a href="/'.$this->getTag($layer).'">'.$layer.'</a></li>';
        $entries = (!empty($entries))? '<ul style="display:block;">'.$entries.'</ul>':$entries;
        return $entries;
    //populates href with tag if one is available, converts text to lower case
    function getTag($label){
        foreach($this->categoryData as $category){
                return $category->getTag();
        return '#'.  strtolower($label);
    //determines if child is associated with all parents provided
    function isLayerParentMatch($child,$parent){
        if(empty($child) || empty($parent)) return false;
        foreach($this->categoryData as $category){
            if(!is_array($parent) && strcmp($category->getGender(),$parent)==0 && strcmp($category->getCategory(),$child)==0)
                return true;
            }else if(strcmp($category->getGender(),$parent[0])==0 
                    && strcmp($category->getCategory(),$parent[1])==0
                    && strcmp($category->getLabel(),$child)==0){
                return true;
        return false;
    function getSideMenu(){
            return $this->sideMenu;

    Please also note, that I converted the json data into a PHP class of Category in which I had getters and setters for each of the attributes defined in the json data. This class has also been omitted from this code.

    点赞 评论 复制链接分享