By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,407 Members | 1,583 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,407 IT Pros & Developers. It's quick & easy.

Storing a Hierarchy in an Array

P: n/a
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.

Jul 17 '05 #1
Share this Question
Share on Google+
8 Replies


P: n/a
vc*******@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
Jul 17 '05 #2

P: n/a
> $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
Jul 17 '05 #3

P: n/a
> 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
Jul 17 '05 #4

P: n/a
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.

Jul 17 '05 #5

P: n/a
vc*******@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/

Jul 17 '05 #6

P: n/a
vc*******@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
Jul 17 '05 #7

P: n/a
On 15 May 2005 01:20:21 -0700, "R. Rajesh Jeba Anbiah"
<ng**********@rediffmail.com> wrote:
vc*******@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. :-)
Jul 17 '05 #8

P: n/a
> 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.
Jul 17 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.