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);
?>
精彩评论