2016-11-28 90 views
1

我有一個PHP多維數組,每個節點都列出它下面的父節點。我試圖轉換數組,以便輸出列表分層列出每個節點列出任何子節點,並只列出數組中的唯一路徑。PHP多維數組找到所有唯一路徑

例如該輸入數組:

$input = [ 

     [ 
      "name" => "home", 
      "parents" => [], 
     ], 
     [ 
      "name" => "newslist", 
      "parents" => [ 
       [ 
        "name" => "home", 
        "parents" => [], 
       ], 
      ], 
     ], 
     [ 
      "name" => "newsdetail", 
      "parents" => [ 
       [ 
        "name" => "newslist", 
        "parents" => [ 
         [ 
          "name" => "home", 
          "parents" => [], 
         ], 
        ], 
       ], 
       [ 
        "name" => "home", 
        "parents" => [], 
       ], 
      ], 
     ], 
     [ 
      "name" => "knowledge", 
      "parents" => [], 
     ], 
    ]; 

應該輸出數組:

$output = [ 
     [ 
      "name" => "home", 
      "children" => [ 
       [ 
        "name" => "newslist", 
        "children" => [ 
         [ 
          "name" => "newsdetail", 
          "children" => [], 
         ], 
        ], 
       ], 
      ], 
     ], 
     [ 
      "name" => "knowledge", 
      "children" => [], 
     ], 
    ]; 
+4

請發表您已嘗試過的內容......您的代碼/研究 –

+0

歡迎使用StackOverflow!請看[如何提出問題](http://stackoverflow.com/help/how-to-ask)鼓勵人們回答你的問題。 – Nytrix

回答

0

這或許可以在一個更漂亮的方式來實現,但這種方法的工作原理。只是程序功能作爲概念證明。

<?php 

$input = [ 

    [ 
     "name" => "home", 
     "parents" => [], 
    ], 
    [ 
     "name" => "newslist", 
     "parents" => [ 
      [ 
       "name" => "home", 
       "parents" => [], 
      ], 
     ], 
    ], 
    [ 
     "name" => "newsdetail", 
     "parents" => [ 
      [ 
       "name" => "newslist", 
       "parents" => [ 
        [ 
         "name" => "home", 
         "parents" => [], 
        ], 
       ], 
      ], 
      [ 
       "name" => "home", 
       "parents" => [], 
      ], 
     ], 
    ], 
    [ 
     "name" => "knowledge", 
     "parents" => [], 
    ], 
]; 

//recursively get all parents and the level the parent is at 
function getParents($nodes,$level,&$parents) 
{ 
    foreach($nodes AS $key => $node) 
    { 
     $parents[ $node['name'] ] = array("name" => $node['name'], "level" => $level); 
     if(isset($node['parents']) && !empty($node['parents'])) 
     { 
      $level += 1; 
      getParents($node['parents'],$level,$parents); 
     } 
    } 
} 

//sort the parents by level 
function sortParentsByLevel($a, $b) 
{ 
    if ($a['level'] == $b['level']) { 
     return 0; 
    } 
    return ($a['level'] > $b['level']) ? -1 : 1; 
} 

//find the output path based on parents array to add new value to 
function setValueFromPath(&$paths, $parents, $value) 
{ 
    $dest = &$paths; 

    if(empty($parents)) 
    { 
     if(!isset($dest[$value])) 
      $dest[$value] = array(); 

    } else { 

     $finalNode = array_pop($parents); 

     foreach ($parents as $parent) 
     { 
      $dest = &$dest[$parent]; 
     } 

     $dest[$finalNode][$value] = array(); 

    } 

} 

//init new variable 
$output = array(); 

//loop through each input node 
foreach($input AS $key => $node) 
{  

    //init a parent array 
    $parents = array(); 

    //if we have parents use the getParents method to set them 
    if(isset($node['parents']) && is_array($node['parents']) && !empty($node['parents'])) 
    { 
     getParents($node['parents'],1,$parents); 
    } 

    //sort the parents according to their level 
    uasort($parents, 'sortParentsByLevel'); 

    //we're only interested in the associative key 
    $parentKeys = array(); 
    foreach($parents AS $parent) 
    { 
     $parentKeys[] = $parent['name']; 
    } 

    //add the $node['name'] value in the appropriate parent array 
    setValueFromPath($output, $parentKeys, $node['name']); 

} 

echo '<pre>'; 
print_r($output); 
echo '</pre>'; 
die(); 

/* 
Array 
(
    [home] => Array 
     (
      [newslist] => Array 
       (
        [newsdetail] => Array 
         (
         ) 

       ) 

     ) 

    [knowledge] => Array 
     (
     ) 

) 
*/