PHP array infinite hierarchical data hierarchical processing code

  • 2020-05-27 04:31:30
  • OfStack


/**
 *  Create a parent tree array 
 *  parameter 
 * $ar  An array of data organized by adjacency lists 
 * $id  The subscript or associated key name used as the primary key in an array 
 * $pid  The subscript or associated key name that is the parent key in the array 
 *  return   Multidimensional array 
 **/
function find_parent($ar, $id='id', $pid='pid') { 
  foreach($ar as $v) $t[$v[$id]] = $v;
  foreach ($t as $k => $item){
    if( $item[$pid] ){
      if( ! isset($t[$item[$pid]]['parent'][$item[$pid]]) )
         $t[$item[$id]]['parent'][$item[$pid]] =& $t[$item[$pid]];
          $t[$k]['reference'] = true;
    }
  } 
  return $t;
}
/**
 *  Create a tree array of child nodes 
 *  parameter 
 * $ar  An array of data organized by adjacency lists 
 * $id  The subscript or associated key name used as the primary key in an array 
 * $pid  The subscript or associated key name that is the parent key in the array 
 *  return   Multidimensional array 
 **/
function find_child($ar, $id='id', $pid='pid') {
  foreach($ar as $v) $t[$v[$id]] = $v;
  foreach ($t as $k => $item){
    if( $item[$pid] ) {
      $t[$item[$pid]]['child'][$item[$id]] =& $t[$k];
      $t[$k]['reference'] = true;
    }
  }
  return $t;
}

Example:

$data = array( 
    array('ID'=>1, 'PARENT'=>0, 'NAME'=>' My grandfather '), 
    array('ID'=>2, 'PARENT'=>1, 'NAME'=>' father '), 
    array('ID'=>3, 'PARENT'=>1, 'NAME'=>' uncles '), 
    array('ID'=>4, 'PARENT'=>2, 'NAME'=>' oneself '), 
    array('ID'=>5, 'PARENT'=>4, 'NAME'=>' son ')
); 
$p = find_parent($data, 'ID', 'PARENT'); 
$c = find_child($data, 'ID', 'PARENT');

The above two methods are to amortize all nodes into an array by id, then find their parent or children, and hook the amortized elements under parent and children by reference.
However, the referenced elements still exist in the amortized array, so in practice, it is best to mark those referenced elements to avoid starting with them as the root and causing duplication.

        foreach ($p as $key => $item) {
            if($item['reference']) continue;
            print_r($item);
        }
        foreach ($c as $key => $item) {
            if($item['reference']) continue;
            print_r($item);
        }

Recursion, after the PHP array element is deleted, the array cursor will return to zero. Therefore, during the traversal process, some elements that have found the "destination" will have to stay in the array, and the search range of subsequent elements cannot be reduced:

$mylist = array(array( 'parent_id'=>0,'id'=>1),
                    array( 'parent_id'=>0,'id'=>2),
                    array( 'parent_id'=>0,'id'=>3),    
                    array( 'parent_id'=>2,'id'=>4),
                    array( 'parent_id'=>2,'id'=>5),
                    array( 'parent_id'=>3,'id'=>6),
                    array( 'parent_id'=>3,'id'=>7),    
                    array( 'parent_id'=>4,'id'=>8),
                    array( 'parent_id'=>5,'id'=>9),
                    array( 'parent_id'=>5,'id'=>10)
                );
    function _findChildren($list, $p_id){    // Data hierarchy, 
          $r = array();
          foreach($list as $id=>$item){
            if($item['parent_id'] == $p_id) {
                   $length = count($r);
                  $r[$length] = $item;
                  if($t = $this->_findChildren($list, $item['id']) ){
                      $r[$length]['children'] = $t;
                  }                
            }
          }
          return $r;
    }  
print_r(_findChildren($mylist, 0));


Related articles: