Advertisement
rfv123

questions/30299576/build-paths-of-all-paths-of-a-tree-struct

Jan 20th, 2016
909
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 5.50 KB | None | 0 0
  1. <?php // http://stackoverflow.com/questions/30299576/build-paths-of-all-paths-of-a-tree-structured-array-in-php
  2.  
  3. $tree = Array(
  4. 0 => Array(
  5.         "name" => 'Furniture',
  6.         "slug" => 'furniture',
  7.         "children" => Array(
  8.                 "0" => Array
  9.                     (
  10.                         "name" => 'Sofa',
  11.                         "slug" => 'sofa',
  12.                         "leafs" => Array
  13.                             (
  14.                                "0" => Array ( "name" => '3 Seater', "slug" => '3-seater'),
  15.                                "1" => Array ( "name" => '4 Seater', "slug" => '4-seater'),
  16.                             ),
  17.  
  18.                     ),
  19.  
  20.                 "1" => Array
  21.                     (
  22.                         "name" => 'Chairs',
  23.                         "slug" => 'chairs',
  24.                         "leafs" => Array
  25.                             (
  26.                                "0" => Array ( "name" => '3 Seater', "slug" => '3-seater'),
  27.                                "1" => Array ( "name" => '4 Seater', "slug" => '4-seater'),
  28.                             )
  29.  
  30.                     )
  31.  
  32.             )
  33.  
  34.     ),
  35.  
  36. 1 => Array(
  37.         "name" => 'Furniture1',
  38.         "slug" => 'furniture1',
  39.         "children" => Array(
  40.                 "0" => Array(
  41.                         "name" => 'Sofa1',
  42.                         "slug" => 'sofa1',
  43.                         "leafs" => Array(
  44.                                "0" => Array ( "name" => '3 Seater1', "slug" => '3-seater1'),
  45.                                "1" => Array ( "name" => '4 Seater1', "slug" => '4-seater1'),
  46.                             )
  47.  
  48.                     ),
  49.  
  50.                 "1" => Array(
  51.                         "name" => 'Chairs1',
  52.                         "slug" => 'chairs1',
  53.                         "leafs" => Array(
  54.                                "0" => Array ( "name" => '3 Seater1', "slug" => '3-seater1'),
  55.                                "1" => Array ( "name" => '4 Seater1', "slug" => '4-seater1')
  56.                             )
  57.                     )
  58.             )
  59.     )
  60. );
  61.  
  62.  
  63. echo '<pre>';
  64. print_r($tree);
  65. echo '</pre>';
  66.  
  67. /* --------------------------------------------------------------------------
  68.  *  Run the program
  69.  */
  70.  
  71. // This really should be class. Later...
  72.  
  73. /* -------------------------------------
  74.  * Store all the paths in here...
  75.  */
  76. $allPaths = array();
  77.  
  78. /* -------------------------------------
  79.  * The 'current' path to the leaf node
  80.  *
  81.  * This is a 'stack'. The 'path' is all the entries combined.
  82.  *
  83.  * @var array
  84.  */
  85. $currentPath = array(); // this is a 'stack'
  86.  
  87. walkTree($allPaths,       // reference
  88.          $currentPath,    // reference
  89.          $tree,
  90.          'children',
  91.  
  92.          /**
  93.           * The closure that is run for each 'leaf' node only currently
  94.           * It could be called on every node if required.
  95.           *
  96.           * @param array currentPath to this value
  97.           * @param array node - the actual leaf data
  98.           * @param string nodeType - leaf or children
  99.           */
  100.          function(array $currentPath,
  101.                    $node,
  102.                    $nodeType = 'leaf')  {
  103.             $fullPath = '';
  104. //            var_dump(__FILE__.__LINE__, 'closure start:',  $node);
  105.  
  106.             if ($nodeType === 'leaf') {
  107.                 $fullPath = 'path: '. implode(' / ', $currentPath)
  108.                            .' item: '. $node['name'];
  109.             }
  110.             return $fullPath;
  111.         }
  112. );
  113.  
  114. var_dump(__FILE__.__LINE__, $allPaths);
  115.  
  116. // ----------------------------- end of processing ---------------------------
  117. exit;
  118.  
  119. /*
  120.  * This takes the entire `current tree state` and decides what to do with the current node.
  121.  */
  122.  
  123. /**
  124.  * Apply processing to the current node.
  125.  *
  126.  * @param array $allPaths    -- added to by the 'processNode' closure
  127.  * @param array $currentPath -- the full path to the current data
  128.  * @param array $nodeList    -- all the descendants from this node
  129.  * @param string $nodeListType 'children' or 'leaf'
  130.  * @param closure $processNode -- called to process the current node data
  131.  *                              -- needs the full path to the current node
  132.  * @return void This is all 'side effects'
  133.  */
  134. function walkTree(&$allPaths,
  135.                    &$currentPath,
  136.                    $nodeList,
  137.                    $nodeListType,
  138.                    /* closure */ $processNode)
  139. {
  140. //    var_dump(__FILE__.__LINE__,
  141. //             $currentPath,
  142. //             $nodeList,
  143. //             $nodeListType
  144. //            );
  145.  
  146.     foreach ($nodeList as $key => $nodeValue) {
  147.  
  148.         if ($nodeListType === 'leaf') {
  149.             $allPaths[] = $processNode($currentPath, $nodeValue, $nodeListType);
  150.             continue; // will not recurse again from here.
  151.         }
  152.  
  153.         // this must happen always...
  154. //        var_dump('before processing one node: pushed: '. $nodeValue['name'], $currentPath);
  155.         array_push($currentPath, $nodeValue['name']);
  156.  
  157.         if (isset($nodeValue['children'])) {
  158.             $nodeType = 'children';
  159.             $nodeList = $nodeValue['children'];
  160.         }
  161.         else {
  162.             $nodeType = 'leaf';
  163.             $nodeList = $nodeValue['leafs'];
  164.         }
  165.  
  166.         walkTree($allPaths,
  167.                  $currentPath,
  168.                  $nodeList,
  169.                  $nodeType,
  170.                  $processNode);
  171.  
  172.         $name = array_pop($currentPath);
  173.   //      var_dump('after processing one node: popped: '. $name, $currentPath);
  174.     } // end of current list
  175.     return;
  176. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement