2016-11-17 15 views
0

請參考解決方案,此問題已解決。遞歸 - 如何構造沒有ID的數據樹,數據是模糊的。

我有下面的數據集,沒有提供id,試圖使用遞歸完成這個。

我應該嘗試這個還是應該去另一條路線?因爲沒有ID。

經過對每個屬性的過濾器後,根是性別,節點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' 
    ) 
); 
+0

這是一個簡單的'foreach' - 你有什麼需要使用遞歸的原因嗎? –

+0

@DarraghEnright構建菜單的直接foreach,你能提供一個代碼模板作爲解決方案嗎?我想查看它。 :) – mcv

+0

@RyanVincent是的,我看到了。我認爲提供給我的這些樣本數據實際上缺乏地區。我解決了這個問題,因爲我在下面發佈了我的解決方案。我仍然歡迎任何人發佈更簡單的解決方案。 :) – mcv

回答

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類類別中,我有getter和setter json數據中定義的每個屬性。這個類也被從這個代碼中省略了。