递归 - 如何构建没有id的数据树,数据是不确定的。

时间:2016-11-17 18:22:58

标签: php recursion

请参考解决方案,这已经解决了。

我有以下数据集,并且没有提供任何ID,尝试使用递归完成此操作。

我应该尝试这个还是应该走另一条路?因为没有ids。

对每个属性进行过滤后,根是性别,节点1是类别,结束节点是标签。我曾尝试使用array_merge_recursive,array_push,我试图构建自己的递归模式,但似乎没有任何东西可以获得我想要的模式。

JSON数据:

[{"label":"Shirts","tag":"M_SHIRT","gender":"Men","category":"Clothing"},
{"label":"Pants","tag":"M_PANT","gender":"Men","category":"Clothing"},
{"label":"Shorts","tag":"M_SHORT","gender":"Men","category":"Clothing"},
{"label":"Casual","tag":"M_SHOE_CASUAL","gender":"Men","category":"Shoes"},
{"label":"Tennis","tag":"M_SHOE_TENNIS","gender":"Men","category":"Shoes"},
{"label":"Watches","tag":"M_ACCESS_WATCH","gender":"Men","category":"Accessories"},
{"label":"Belts","tag":"M_ACCESS_BELT","gender":"Men","category":"Accessories"},
{"label":"Ties","tag":"M_ACCESS_TIE","gender":"Men","category":"Accessories"}]

Men
 ->Accessories 
   ->Watches
   ->Belts
   ->Ties
 ->Clothing
   ->Pants
   ->Shirts
   ->Shorts  
 ->Shoes
   ->Casual
   ->Tennis

这是我递归的PHP代码,它很乱:

  function buildSideBar($searchLayers){
        try{
            $sidebar;
            $count = 0;
            foreach($searchLayers[$count] as $root){
                //$sideBarData[]=array("root"=>$root);
                $sideBarData[]=$root;
                $searchLayers[$count]='';
                $this->addChildren($sideBarData,$searchLayers,1,$root, $count);
                $count++;
            }
            var_dump($sideBarData);
        }catch (Exception $ex){
            log($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
                if($this->verifyChildBelongsToParent($child,$parent)){
                    if($level==1)
                    {
                        $count = 0;
                       // $sideBarData = array_merge_recursive($sideBarData, array("root"=>array("child".$level=>$child)));
                        $sideBarData[0][$level] = $child;
                    }
                    else
                    {
                        $sideBarData[][][$level] = $child;
                    }
                    $parents[]=$parent;
                    $parents[]=$child;
                    //var_dump($parents);
                    if($level<3)
                    {
                      //  $this->addChildren($sideBarData,$layers,$level++,$parents);
                    }

                }

                //
            }
        }

    }

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

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

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

            }
            else{
                //echo 'check if ' . $parent .' has child ' . $child;
                if(strcmp($category->getGender(),$parent)==0)
                {
//                    var_dump($parent);
//                    var_dump($child);
                   // echo 'Add Child';
                    return true;
                }

            }
        }
        return false;


    }

这是我传入的$ searchLayers数据:

Array
(
    [0] => "MEN",
    [1] => Array(
          [0]=>'Accessories',
          [1]=>'Clothing',
          [2]=>'Shoes'
        ),
    [2] =>Array(
          [0]=>'Belts',
          [1]=>'Casual',
          [2]=>'Shirts',
          [3]=>'Shorts',
          [4]=>'Tennis',
          [5]=>'Ties',
          [6]=>'Watches'
    )
);

1 个答案:

答案 0 :(得分:0)

所以这是我的解决方案,可能有更好的解决方案,但我尝试了3种不同的技术,总是认为这可以扩展。

我在设计上设置了以下限制,侧面菜单栏只能是3级深度。

有了这个,我最初对数据进行了排序,以找出上面$searchLayers中详述的祖父母,父母,孩子,但我将其传递为3个独立的数组($layer1, $layer2, $layer3),这些数组符合父母的等级制度。

以下是代码,它们都是通过调用最顶层的函数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->isLayerParentMatch($layer,$parent)){
            //if this child has it's own childern, process needs to be repeated, else child is an leaf (aka end node)
            if(!empty($layer2)){
                $entries .= '<li><a class="expandable" href="/'.$this->getTag($layer).'">'.$layer.'</a></li>';
                $entries .= $this->buildSideMenuChildern(array($parent,$layer),$layer2);
            }else{
                $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){
        if(strcmp($label,$category->getLabel())==0)
        {
            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;
}

还请注意,我将json数据转换为类别的PHP类,其中我为json数据中定义的每个属性都有getter和setter。此代码中也省略了该类。