开发者

PHP: reorder array to show hierarchy

How can I turn the first array in to the second one? The goal is to create an array that shows the hierarchy, based on location_id and parent_id. Each location_name should be in an array of which the key is its parent_id.

Ignore the values I gave to location_name. No value for parent_id == NULL, these are the top level items.

First array:

    Array
    (
        [0] => stdClass Object
            (
                [location_id] => 1
                [location_name] => Town 1
                [parent_id] => 
            )

        [1] => stdClass Object
            (
                [location_id] => 2
                [location_name] => Town 1.1
                [parent_id] => 
            )

        [2] => stdClass Object
            (
                [location_id] => 3
                [location_name] => Town 1.2
                [parent_id] => 1
            )

        [3] => stdClass Object
            (
                [location_id] => 4
                [location_name] => Town 1.3
                [parent_id] => 1
            )

        [4] => stdClass Object
            (
                [location_id] => 5
                [location_name] => town 1.1.1
                [parent_id] => 2
            )

        [5] => stdClass Object
            (
                [location_id] => 6
                [location_name] => Town 1.1.2
                [parent_id] => 3
            )
);

Resulting array should be:

Array(
        'Town 1' = array(
            'town 1.2',
            'town 1.3'开发者_运维知识库 = array(
                 'town 1.1.2'
             )
        ),
        'Town 2' = array(
             'town 1.1.1'
        )
    );

EDIT: working solution based on Rijk's answer

function _order_locs($parent, $array)
    {
        $return = array();
        foreach ( $array as $town )
        {
            if ( $town->parent_id == $parent )
            {
                $set = $this->_order_locs( $town->location_id, $array );               
                if( $this->_menu_is_parent($town->location_id, $array) ) $return[$town->location_name] = $set;
                else $return[] = $town->location_name;            
            }
        }

        return $return;
    }

    function _menu_is_parent($id, $array)
    {
        foreach( $array as $a )
        {
            if( $a->parent_id == $id ) return TRUE;
        }
    }


You have to loop through it, using a recursive function (one that calls itself):

function getChilds( $parent, $array ) {
    $return = array();
    foreach ( $array as $town ) {
        if ( $town['location_id'] == $parent ) {
            $return[] = array(
                'name' => $town['location_name'],
                'childs' => getChilds( $town['location_id'], $array )
            );
        }
    }
    return $return;
}

$towns_tree = getChilds( 0, $towns );

Might not work right off the bat, but that gives you a nice oppurtunity to play with the code and get familiar with this concept ;)


Here is some code that will more or less do what you need. You will have to tweak it to your liking.

<?php

Class Node {
   public $id;
   public $parent_id;
   public $value;
   public $children;
   public $depth;

   function __construct($id, $parent_id, $value) {
      $this->id = $id;
      $this->parent_id = $parent_id;
      $this->value = $value;
          $this->children = array();
      $this->depth = 0;
   }

   function add_child(Node $new_child) {
      if ($new_child->parent_id == $this->id) {
         $this->children[$new_child->id] = $new_child;
         $this->children[$new_child->id]->depth = $this->depth + 1;
      } else {
         foreach ($this->children as $child) {
            $child->add_child($new_child);
         }
      }
   }

   function to_array() {
      if (count($this->children) > 0) {
         $arr = array();
         foreach ($this->children as $child) {
            array_push($arr, $child->to_array());
         }
         return array($this->value => $arr);
      } else {
         return $this->value;
      }
   }

   function str() {
      echo str_repeat(" ", $this->depth) . $this->value . "\n";
      foreach ($this->children as $child) {
         $child->str();
      }
   }
}

?>

Here is some sample code to test it with:

<?php

$arr = Array(
   array('location_id' => 1,
         'location_name' => 'Town 1',
         'parent_id' => 0),

   array('location_id' => 2,
         'location_name' => 'Town 1.1',
         'parent_id' => 0),

   array('location_id' => 3,
         'location_name' => 'Town 1.2',
         'parent_id' => 1),

   array('location_id' => 4,
         'location_name' => 'Town 1.3',
         'parent_id' => 1),

   array('location_id' => 5,
         'location_name' => 'Town 1.1.1',
         'parent_id' => 2),

       array('location_id' => 6,
         'location_name' => 'Town 1.1.2',
         'parent_id' => 3)
);

$root = new Node(0, 0, 'root');
foreach ($arr as $item) {
   $node = new Node($item['location_id'],
                    $item['parent_id'],
                    $item['location_name']);
   $root->add_child($node);
}
$tree = $root->to_array();
$tree = $tree['root'];
var_dump($tree);

?>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜