Storing a Hierarchy in an Array

This is a discussion on Storing a Hierarchy in an Array within the PHP Language forums, part of the PHP Programming Forums category; Hello all, Okay, I am having some troubles. What I am doing here is dealing with an employee hierarchy that ...


Go Back   Usenet Forums > PHP Programming Forums > PHP Language

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 05-14-2005
vcardillo@gmail.com
 
Posts: n/a
Default Storing a Hierarchy in an Array

Hello all,

Okay, I am having some troubles. What I am doing here is dealing with
an employee hierarchy that is stored in an array. It looks like this:

$employees = array( "user_id" => array( "name", "title",
"reports to user id", "start date in the format: mm/dd/yyyy" )
);

How can I display this hierarchy in simple nested <li> tags in the most
efficient way possible? I realize that the way this is setup, the
hierarchy is essentially a tree. But I am at a loss as to how to pull
this data out, sort it, and display it wit nested <li> tags. I am
thinking that this is more of a computer science problem....

What I mean by displayed as a hierarchy, is that the nested <li> tags
will indent themselves to look like that. Like this:

- CEO
-- Manager
--- Manager's secretary
--- Minion
-- Manager


That sort of thing. I am just lost as to how I can analyze the
structure of the array and turn it in to output like that.

Any help is greatly appreciated.

Reply With Quote
  #2 (permalink)  
Old 05-15-2005
Zilla
 
Posts: n/a
Default Re: Storing a Hierarchy in an Array

vcardillo@gmail.com wrote:
[snip]
> How can I display this hierarchy in simple nested <li> tags in the most
> efficient way possible?

[snip]

<?php
echo "<ul>";
foreach($employees as $key => $value) {
echo "<li>" . $key . "</li>";
echo "<ul>";
foreach($value as $value2) {
echo "<li>" . $value2 . "</li>";
}
echo "</ul>";
}
echo "</ul>";
?>

Would look like this:

user_id
name
title
reports to user id
start date in the format: mm/dd/yyyy
another user_id
another name
another title
another reports to user id
another start date in the format: mm/dd/yyyy

....and so on.

Zilla
Reply With Quote
  #3 (permalink)  
Old 05-15-2005
Mike Willbanks
 
Posts: n/a
Default Re: Storing a Hierarchy in an Array

> $employees = array( "user_id" => array( "name", "title",
> "reports to user id", "start date in the format: mm/dd/yyyy" )
> );
> How can I display this hierarchy in simple nested <li> tags in the most
> efficient way possible? I realize that the way this is setup, the
> hierarchy is essentially a tree. But I am at a loss as to how to pull
> this data out, sort it, and display it wit nested <li> tags. I am
> thinking that this is more of a computer science problem....
>
> What I mean by displayed as a hierarchy, is that the nested <li> tags
> will indent themselves to look like that. Like this:
>
> - CEO
> -- Manager
> --- Manager's secretary
> --- Minion
> -- Manager
>
>
> That sort of thing. I am just lost as to how I can analyze the
> structure of the array and turn it in to output like that.


What I see is that the data is not really designed so well in the array
in the first place. You may try and organize it better for what you are
doing. What I mean by this, is that the data is organized is such a
form that all the CEO's are in one part of the array and the mangagers
are under them etc etc.

The next thing is you should be using a recursive function.

Mike
Reply With Quote
  #4 (permalink)  
Old 05-15-2005
Mike Willbanks
 
Posts: n/a
Default Re: Storing a Hierarchy in an Array

> Would look like this:
>
> user_id
> name
> title
> reports to user id
> start date in the format: mm/dd/yyyy
> another user_id
> another name
> another title
> another reports to user id
> another start date in the format: mm/dd/yyyy


Hmmm maybe I missed the point on my reply lol!

Mike
Reply With Quote
  #5 (permalink)  
Old 05-15-2005
vcardillo@gmail.com
 
Posts: n/a
Default Re: Storing a Hierarchy in an Array

No... you're right. Let's say we have this stored in the array,
conceptually:

A reports to B.
B reports to C.
D Reports to C.
E Reports to C.
C Reports to Z
G Reports to Z.

The data has to be formatted like this:

CEO Z
- Person C
-- Person B
--- Person A
-- Person D
-- Person E
- Person G

Each dash (-) should be understood as a tab, and a different bulleted
symbol. This is essentially what I mean. The data can't just be
outputted linearly. The LI tags have to be nested, so as to create the
visual hierarchy.... this is why I am finding it so difficult. The
data structure doesn't really allow for this.

Reply With Quote
  #6 (permalink)  
Old 05-15-2005
R. Rajesh Jeba Anbiah
 
Posts: n/a
Default Re: Storing a Hierarchy in an Array

vcardillo@gmail.com wrote:
> No... you're right. Let's say we have this stored in the array,
> conceptually:
>
> A reports to B.
> B reports to C.
> D Reports to C.
> E Reports to C.
> C Reports to Z
> G Reports to Z.
>
> The data has to be formatted like this:
>
> CEO Z
> - Person C
> -- Person B
> --- Person A
> -- Person D
> -- Person E
> - Person G


Sounds like a tree data structure to me. Searching for array
implementation of tree and traversing algorithms might help.

--
<?php echo 'Just another PHP saint'; ?>
Email: rrjanbiah-at-Y!com Blog: http://rajeshanbiah.blogspot.com/

Reply With Quote
  #7 (permalink)  
Old 05-15-2005
Zilla
 
Posts: n/a
Default Re: Storing a Hierarchy in an Array

vcardillo@gmail.com wrote:
> A reports to B.
> B reports to C.
> D Reports to C.
> E Reports to C.
> C Reports to Z
> G Reports to Z.


Oh like that.... then my example doesn't work.... i will think about it
and maybe give a reply later... have to work now...

Zilla
Reply With Quote
  #8 (permalink)  
Old 05-15-2005
Matt
 
Posts: n/a
Default Re: Storing a Hierarchy in an Array

On 15 May 2005 01:20:21 -0700, "R. Rajesh Jeba Anbiah"
<ng4rrjanbiah@rediffmail.com> wrote:

>vcardillo@gmail.com wrote:
> Sounds like a tree data structure to me. Searching for array
>implementation of tree and traversing algorithms might help.


I agree that you are probably looking at a tree structure rather than
an array. Personally I would also use classes to encapsulate the
employees (each employee is effectively a node in the tree) i.e:

class cEmployee {
var $m_userId;
var $m_name;
var $m_title;
var $m_startDate;
var $m_subordinates = array();
function cEmployee($userId,$name,$title,$startDate)
{
$this->m_userId = $userId;
$this->m_name = $name;
$this->m_title = $title;
$this->m_startDate = $startDate;
}
function addSubordinate($item)
{
$this->m_subordinates[] = $item;
}
};

To traverse the tree you would need a function along these lines:

function traverse($h)
{
echo "<ul><li>";
echo $h->m_title;
while (list($key, $val) = each($h->m_subordinates))
{
traverse($val);
}
echo "</li></ul>\n";
};

This is not perfect as even employees who have no subordinates are
still an unordered list themselves i.e:

<ul><li>CEO<ul><li>Manager<ul><li>Managers Secretary</li></ul>
<ul><li>Minion</li></ul>
</li></ul>
<ul><li>Manager</li></ul>
</li></ul>

Then there is also the task of populating the tree to begin with. I
will leave that to you. To get the printout above I used the following
code:

$employeelist = new cEmployee('','','CEO','');
$employeelist->addSubordinate(new cEmployee('','','Manager',''));
$employeelist->m_subordinates[0]->addSubordinate(new
cEmployee('','','Managers Secretary',''));
$employeelist->m_subordinates[0]->addSubordinate(new
cEmployee('','','Minion',''));
$employeelist->addSubordinate(new cEmployee('','','Manager',''));
traverse($employeelist);

Have fun. :-)
Reply With Quote
  #9 (permalink)  
Old 05-19-2005
Zilla
 
Posts: n/a
Default Re: Storing a Hierarchy in an Array

> How can I display this hierarchy in simple nested <li> tags in the most
> efficient way possible?


Now I have had the time to look at your problem. Here is what I came up
with. Remember that the CEO(s) should report to themselves or else it
wont work (look at id 1 and 2 which are CEOs).

I used this array to test with:

$employees = array(1 => array("name1", "title1", 1, "date1"),
2 => array("name2", "title2", 2, "date2"),
33 => array("name3", "title3", 15, "date3"),
15 => array("name4", "title4", 10, "date4"),
10 => array("name5", "title5", 1, "date5"),
37 => array("name6", "title6", 15, "date6"),
40 => array("name7", "title7", 33, "date7"),
45 => array("name8", "title8", 10, "date8"),
50 => array("name9", "title9", 37, "date9"),
4 => array("name10", "title10", 2, "date10"),
7 => array("name11", "title11", 23, "date11"),
456 => array("name12", "title12", 50, "date12"),
89 => array("name13", "title13", 4, "date13"),
23 => array("name14", "title14", 25, "date14"),
57 => array("name15", "title15", 45, "date15"),
25 => array("name16", "title16", 4, "date16")
);

And here's the code:

<?php
//builds an array of relations in format the id1_id2 where
//id2 reports to id1
foreach($employees as $key => $value) {
if($value[2] != $key) {
$relations[] = $value[2] . "_" . $key;
}
}
//sort the array in a natural order
natsort($relations);
//this function builds an array with flat tree structures
//in the format id1_id2_id3_id4_....idx
function make_tree_structure($array) {
$array2 = $array;
$i = 0;
while(list($key, $value) = each($array)) {
$explode = explode("_", $value);
$n = count($explode);
$n = $n - 1;
$under = $explode[$n];
while(list($key2, $value2) = each($array2)) {
if($key != $key2) {
$explode2 = explode("_", $value2);
$n2 = count($explode2) - 1;
$under2 = "";
while($n2 > 0) {
$under2 = $explode2[$n2] . "_" . $under2;
$n2--;
}
$under2 = substr($under2, 0, -1);
$over2 = $explode2[0];
if($over2 == $under) {
$newarray[] = $value . "_" . $under2;
$i = 1;
$x = 1;
unset($array[$key2]);
unset($array2[$key2]);
}
}
}
if($i == 1) {
unset($array[$key]);
unset($array2[$key]);
$i = 0;
}
reset($array2);
}
foreach($array as $value) {
$newarray[] = $value;
}
natsort($newarray);
if($x == 1) {
$newarray = make_tree_structure($newarray);
} else {
$newarray = $array;
}
return $newarray;
}
$flat_tree_structure = make_tree_structure($relations);
//builds a multidimensional array from the flat structures
function build_multidimensional_array($array) {
foreach($array as $value) {
$explode = explode("_", $value);
$string = "";
foreach($explode as $value2) {
$string = $string . "[" . $value2 . "]";
}
$string = "\$newarray" . $string . " = 0;";
eval($string);
}
return $newarray;
}
$tree_structure = build_multidimensional_array($flat_tree_structure) ;
//loops over the multidimensional array and outputs nested lists
function output_nested_lists($array, $employees) {
foreach($array as $key => $value) {
echo "<ul>\n";
echo "<li>" . $employees[$key][1] . "</li>\n"; //You
could change this...
if(is_array($value)) {
output_nested_lists($value, $employees);
}
echo "</ul>\n";
}
}
output_nested_lists($tree_structure, $employees);
?>

Outputs this with the example employees array:

* title1
o title5
+ title4
# title3
* title7
# title6
* title9
o title12
+ title8
# title15
* title2
o title10
+ title16
# title14
* title11
+ title13

If you want the name to be written just use $employees[$key][0] where I
wrote "//You could change this".

Zilla.
Reply With Quote
Reply
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On




All times are GMT +1. The time now is 11:36 AM.


Powered by vBulletin® Version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO 3.0.0