471,306 Members | 863 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,306 software developers and data experts.

Help needed to build an array

Hi

I have a table with something like

ID PARENT

0 | -1
1 | -1
2 | 1
3 | 1
4 | 2
5 | -1
6 | 4

And i want to build an array so i can output the data in the form

0
1
|--2
|----4
| |----5
|--3
5

Where 2 is a child of 1, and 4 is a child of 2 and so on.
I could create an array like $data[$id][$parent] but how would i output the
data where i get all the children of, say, ID=1 and all the children of ID =
4.
What would be the best way to achieve the above using MySQL db and php?

If i read all the data sorted by PARENT i might be able to read the whole
table at once and add all the data to one array?

Any ideas?

Regards.
Simon/
Jul 17 '05 #1
10 2075
Children and Parents aren't used in Arrays, are you using Objects or
Arrays???

"Sims" <si*********@hotmail.com> schreef in bericht
news:c1*************@ID-162430.news.uni-berlin.de...
Hi

I have a table with something like

ID PARENT

0 | -1
1 | -1
2 | 1
3 | 1
4 | 2
5 | -1
6 | 4

And i want to build an array so i can output the data in the form

0
1
|--2
|----4
| |----5
|--3
5

Where 2 is a child of 1, and 4 is a child of 2 and so on.
I could create an array like $data[$id][$parent] but how would i output the data where i get all the children of, say, ID=1 and all the children of ID = 4.
What would be the best way to achieve the above using MySQL db and php?

If i read all the data sorted by PARENT i might be able to read the whole
table at once and add all the data to one array?

Any ideas?

Regards.
Simon/

Jul 17 '05 #2
Hi,

"John Smith" <so*****@nobody.com> wrote in message
news:c1**********@news3.tilbu1.nb.home.nl...
Children and Parents aren't used in Arrays, are you using Objects or
Arrays???

I am not using anything yet, i just want to know what would be the best way
to read the data
so that i can get the children(s) of all ids.

It could be a class i guess, I want a function that would read the data from
the database and build all the parents recursively so that i could, for
example, get all the children for ID = 1 and i would return 2, 3.

I want to build the array/class in one call of the database and not all
every time i need to find the child of an ID.
ID PARENT

0 | -1
1 | -1
2 | 1
3 | 1
4 | 2
5 | -1
6 | 4

And i want to build an array so i can output the data in the form

0
1
|--2
|----4
| |----5
|--3
5

Where 2 is a child of 1, and 4 is a child of 2 and so on.
I could create an array like $data[$id][$parent] but how would i output

the
data where i get all the children of, say, ID=1 and all the children of ID =
4.
What would be the best way to achieve the above using MySQL db and php?

If i read all the data sorted by PARENT i might be able to read the

whole table at once and add all the data to one array?

Any ideas?

Regards.
Simon/


Jul 17 '05 #3
col

"John Smith" <so*****@nobody.com> wrote in message
news:c1**********@news3.tilbu1.nb.home.nl...
Children and Parents aren't used in Arrays, are you using Objects or
Arrays???

"Sims" <si*********@hotmail.com> schreef in bericht
news:c1*************@ID-162430.news.uni-berlin.de...
Hi

I have a table with something like

ID PARENT

0 | -1
1 | -1
2 | 1
3 | 1
4 | 2
5 | -1
6 | 4

And i want to build an array so i can output the data in the form

0
1
|--2
|----4
| |----5
|--3
5

Where 2 is a child of 1, and 4 is a child of 2 and so on.
I could create an array like $data[$id][$parent] but how would i output the
data where i get all the children of, say, ID=1 and all the children of ID =
4.
What would be the best way to achieve the above using MySQL db and php?

If i read all the data sorted by PARENT i might be able to read the

whole table at once and add all the data to one array?

Any ideas?

Regards.
Simon/

think he wants arrays inside arrays... to output.. something like this would
work

foreach($data['array of some sort'] as $key => $value)

{

if(is_array($value))

{

foreach($value as $key1 => $value1)

{

if(is_array($value1))

{

foreach($value1 as $key2 => $value2)

{

do something with $value2

}

}

else { do something with $value1}

}

}

else {do something with $value}

}

not the best way of doing thing but that should get you 3 deep, sure ya see
whats happening
Jul 17 '05 #4
Hi,

think he wants arrays inside arrays... to output.. something like this would work

<snip code>

not the best way of doing thing but that should get you 3 deep, sure ya see whats happening


Thanks but i do not know how deep it goes, maybe that is what i should use a
class.
Where class definition is something like

class ITEMS
{
var $iParent = // int id of parent or -1 if no parent
var $aChildren = // array of class ITEMS or false if no children

// and some functions like
function GetChild( $id )
{
// return the array all the children
}
}

Or something like that.
But i would i build the class.

Simon.
Jul 17 '05 #5
Sims wrote:

Hi

I have a table with something like

ID PARENT

0 | -1
1 | -1
2 | 1
3 | 1
4 | 2
5 | -1
6 | 4

And i want to build an array so i can output the data in the form

0
1
|--2
|----4
| |----5
|--3
5

Where 2 is a child of 1, and 4 is a child of 2 and so on.
I could create an array like $data[$id][$parent] but how would i output the
data where i get all the children of, say, ID=1 and all the children of ID =
4.
What would be the best way to achieve the above using MySQL db and php?

If i read all the data sorted by PARENT i might be able to read the whole
table at once and add all the data to one array?


Try a recursive function and 2 arrays, passed by reference.
Arrays: oldarray()(containing table results) and newarray() (empty)

function makelist(& $oldarray,& $newarray, $id) {
//go through old array, searching for anything with parent $id
//if found, add to new array in correct place, delete from old array and call
makelist with new id
}

Start your function off with $id=-1.
The actual code is a bit trickier than the comments.
Consider what happens if:
-parent doesn't exist
-there are >1 children - how do you suborder them?
-there's a loop (id=>1, parent=>2)(id=>2,parent=>1) //should never happen

Anyway, that should order your stuff.
For echoing the results, you could write a function getindent($id)

function getindent($id, $newarray) {
$indent=0;
$foundit=0;

foreach($newarray as $foo){
if ($foo['id'] == $id) {
$parent=$foo['parent'];
if ($parent == -1)
return $indent;
break;
}
}

while ($foundit==0) {
foreach($newarray as $foo){
if ($parent == $foo['id']) {
$indent++;
if ($foo['parent'] == -1)
return $indent;
$parent = $foo['parent'];
break;
}
}
}
}

This function is untested and likely contains typos and/or small logic errors.
It does not have any failsafes (if an array element has the id of a non-existant
parent or if there's a loop in the parents, as above, it will loop until the
script times out). If you use it, I suggest you improve it.

Then to display:

foreach($newarray as $foo) {
$indents = getindent(-1, $newarray);
for($i=0;$i<$indents;++$i)
echo '-';
echo $foo['id']."<br>";
}

Regards,
Shawn
--
Shawn Wilson
sh***@glassgiant.com
http://www.glassgiant.com
Jul 17 '05 #6
I would strongly disagree with Mr. Smith's broad assertion that children
and parents aren't used in arrays. Arrays are a tool to serve their master.
If I am understanding the goal here, you want to map a parent id to an array
of children id's. Array elements can themselves be arrays, so this is no big
deal. You call the database, say with something like "select * from parent",
and you get back all the rows in your table.

You then iterate through each row in the table, building up your data
structure (I'm assuming -1 is being used here to represent no parent).

#set $n_rows to the number of rows in your table
for ($i = 0; $i < $n_rows; $i++)
{
# get your parent id poked into $pid, child id poked into $cid
if ($pid != -1)
$data[$pid][] = $cid;
}

$data then is built as a 2-D array and comes out looking like:
$data[1] = array(2, 3);
$data[2] = array(4);
$data[4] = array(6);

The formatted output you show below doesn't make any sense to me, so
I'll leave that part to you, but given a parent id, $data maps to an array
of children ID - that is the crux of your issue as I understand it.

Just FYI, this looks like a relatively expensive thing to do - I don't
know anything about caching data from one page invocation to the next, but
unless you have some sort of a caching mechanism you are (potentially)
downloading this whole table and building your mapping on every page
request. Maybe this is in a standalone script so it doesn't matter, or maybe
you don't care about performance anyway - but just something to consider.

HTH,
-ej
"Sims" <si*********@hotmail.com> wrote in message
news:c1*************@ID-162430.news.uni-berlin.de...
Hi,

"John Smith" <so*****@nobody.com> wrote in message
news:c1**********@news3.tilbu1.nb.home.nl...
Children and Parents aren't used in Arrays, are you using Objects or
Arrays???

I am not using anything yet, i just want to know what would be the best

way to read the data
so that i can get the children(s) of all ids.

It could be a class i guess, I want a function that would read the data from the database and build all the parents recursively so that i could, for
example, get all the children for ID = 1 and i would return 2, 3.

I want to build the array/class in one call of the database and not all
every time i need to find the child of an ID.
ID PARENT

0 | -1
1 | -1
2 | 1
3 | 1
4 | 2
5 | -1
6 | 4

And i want to build an array so i can output the data in the form

0
1
|--2
|----4
| |----5
|--3
5

Where 2 is a child of 1, and 4 is a child of 2 and so on.
I could create an array like $data[$id][$parent] but how would i output
the
data where i get all the children of, say, ID=1 and all the children
of
ID
=
4.
What would be the best way to achieve the above using MySQL db and

php?
If i read all the data sorted by PARENT i might be able to read the

whole table at once and add all the data to one array?

Any ideas?

Regards.
Simon/



Jul 17 '05 #7
I would strongly disagree with Mr. Smith's broad assertion that children and parents aren't used in arrays. Arrays are a tool to serve their master. If I am understanding the goal here, you want to map a parent id to an array of children id's. Array elements can themselves be arrays, so this is no big deal. You call the database, say with something like "select * from parent", and you get back all the rows in your table.
i tend to agree with you. Arrays might be the right thing for me.
But an object might also do the trick, i think.

You then iterate through each row in the table, building up your data
structure (I'm assuming -1 is being used here to represent no parent).

<snip code >

All i want is to call the database, "select * from table1"
and then build some form of array/object that will contain
1) It's own ID number
2) The number of it's father, (-1 been no father).

So looking at it like that i could create a class

class DATA_1{
$father;
$number;
}

class DATA_2{
$data_1 = array(); // of class data_1
}

fill the array using a select.

but then how would i output it?
maybe somerecuring function...like

// $data_2 is class DATA_2
function print_tree( $depth, $id )
{
// output the $id using the depth
$data = $data_2->GetChildren( -1 ); would return all the item whose
parent is -1;
foreach( $data as $x ){
print_tree( ($depth+1), $x );
}
}

So the output would print all the father followed by all the children's...

i would start the loop with
print_tree( 0, -1 )

I think...
And that way i would only call the DB once to build the array.

The formatted output you show below doesn't make any sense to me, so
I'll leave that part to you, but given a parent id, $data maps to an array
of children ID - that is the crux of your issue as I understand it.
The formatted thing was just to try to explain what i was after.


Just FYI, this looks like a relatively expensive thing to do - I don't
know anything about caching data from one page invocation to the next, but
unless you have some sort of a caching mechanism you are (potentially)
downloading this whole table and building your mapping on every page
request. Maybe this is in a standalone script so it doesn't matter, or maybe you don't care about performance anyway - but just something to consider.


Yes you are right but it is only used in one page, (for the administrator to
check that the data are still in good order).
And secondly it is only a 10/20 items table max.

But i am always looking for better ways to do things, if you know of a
better way...

Simon.

Jul 17 '05 #8

"Sims" <si*********@hotmail.com> wrote in message
news:c2*************@ID-162430.news.uni-berlin.de...
All i want is to call the database, "select * from table1"
and then build some form of array/object that will contain
1) It's own ID number
2) The number of it's father, (-1 been no father).


This is a *different* (but still trivial) problem. Here's an array
based solution:

#set $n_rows to the number of rows in your table
for ($i = 0; $i < $n_rows; $i++)
{
# get your parent id poked into $pid, child id poked into $cid
$data[$cid] = $pid;
}
The second part, the question that you are hinting at but haven't asked
directly is

"How do I pretty print a textual representation of a general tree?"

That's a very non-trivial problem. In fact, there is nothing here that
even implies a true tree (i.e., there is nothing preventing you from
creating loops in your parent-child table). In the general case, each node
can (recursively) have any number of children. So, I don't have an easy
answer for how you are going to pretty-print that. That doesn't mean it's
impossible to do, just that it's very non-trivial. If you just need to see
the information, go back to my first solution, and recursively iterate
through the keys and print lines like:

parent0: {}
parent1: {child2, child3}
parent2: {child4}
parent3: {}
parent4: {child6}
parent5: {}
parent6: {}

Or use the solution in this post, and print lines like:

child0: NO-parent
child1: NO-parent
child2: parent1
....

For a given node, you will have to trace the lineage through several
lines. But this is essentially just dumping your table.

If you are serious about solving the harder problem, pretty-printing a
general tree, first come up with a textual representation that addresses the
general case. It's silly to waste time taking pot-shots in the dark at code
fragments that sorta-might-maybe-kinda help with a piece of the problem
without first understanding the ultimate goal.

-ej
Jul 17 '05 #9

"Erik Johnson" <ej@just.post.here.com> schreef in bericht
news:40********@news.zianet.com...

"Sims" <si*********@hotmail.com> wrote in message
news:c2*************@ID-162430.news.uni-berlin.de...
All i want is to call the database, "select * from table1"
and then build some form of array/object that will contain
1) It's own ID number
2) The number of it's father, (-1 been no father).
This is a *different* (but still trivial) problem. Here's an array
based solution:

#set $n_rows to the number of rows in your table
for ($i = 0; $i < $n_rows; $i++)
{
# get your parent id poked into $pid, child id poked into $cid
$data[$cid] = $pid;
}
The second part, the question that you are hinting at but haven't

asked directly is

"How do I pretty print a textual representation of a general tree?"

That's a very non-trivial problem. In fact, there is nothing here that
even implies a true tree (i.e., there is nothing preventing you from
creating loops in your parent-child table). In the general case, each node
can (recursively) have any number of children. So, I don't have an easy
answer for how you are going to pretty-print that. That doesn't mean it's
impossible to do, just that it's very non-trivial. If you just need to see
the information, go back to my first solution, and recursively iterate
through the keys and print lines like:

parent0: {}
parent1: {child2, child3}
parent2: {child4}
parent3: {}
parent4: {child6}
parent5: {}
parent6: {}

Or use the solution in this post, and print lines like:

child0: NO-parent
child1: NO-parent
child2: parent1
...

For a given node, you will have to trace the lineage through several
lines. But this is essentially just dumping your table.

If you are serious about solving the harder problem, pretty-printing a
general tree, first come up with a textual representation that addresses the general case. It's silly to waste time taking pot-shots in the dark at code fragments that sorta-might-maybe-kinda help with a piece of the problem
without first understanding the ultimate goal.

-ej

Beware if you're using a loop to print trees, you might get an infinite
(recursive) loop.
e.g.
1 points to 2
2 points to 4
4 points to 3
3 points to 1

Nice to mention is print_r()
It had the same problem, although it's solved now, try print_r($_GLOBALS);


Jul 17 '05 #10

"Sims" <si*********@hotmail.com> schreef in bericht
news:c1*************@ID-162430.news.uni-berlin.de...
Hi,

think he wants arrays inside arrays... to output.. something like this would
work


<snip code>

not the best way of doing thing but that should get you 3 deep, sure ya

see
whats happening


Thanks but i do not know how deep it goes, maybe that is what i should use

a class.
Where class definition is something like

class ITEMS
{
var $iParent = // int id of parent or -1 if no parent
var $aChildren = // array of class ITEMS or false if no children
// and some functions like
function GetChild( $id )
{
// return the array all the children
}
}

Or something like that.
But i would i build the class.

Simon.

Maybe this will help
WARNING untested script so beware of typos and other bad stuff.

$prefix='';
$maintree=array();

print_tree($maintree,$prefix)

function print_tree($tree,$prefix)
{
if(is_array($tree))
{
foreach($tree as $newtree)
{
print_tree($newtree,$prefix.'---');
}
}
else echo $prefix.$tree."<br />\r\n";
}
Jul 17 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by abcd | last post: by
3 posts views Thread by tsunami | last post: by
6 posts views Thread by Ian Gibbons | last post: by
5 posts views Thread by skumar434 | last post: by
2 posts views Thread by rookiejavadude | last post: by
7 posts views Thread by gubbachchi | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.