...

View Full Version : recursive array calculations

manilodisan
05-21-2008, 02:43 PM
I have an array which holds some categories and their info. The categories have subcategories also. Each category has a number of wallpapers attached. What I;m trying to do is build some counter to specify exactly how many subcategories and wallpapers each category has. No matter where in the tree.... I'm sure it can be done recursively somehow but I'm pulling my hair out since last night. I would really appreciate some help. Here's the code till now. You can run it directly as it will print the whole tree:

<?php
function printr ( \$data )
{
echo '<pre>' . print_r ( \$data, TRUE ) . '</pre>';die ();
}

\$categories = array
(
1 => array
(
'ID' => 1,
'subcategories' => 1,
'wallpapers' => 11,
'id_parent' => 0
),
2 => array
(
'ID' => 2,
'subcategories' => 3,
'wallpapers' => 5,
'id_parent' => 1
),
3 => array
(
'ID' => 3,
'subcategories' => 1,
'wallpapers' => 2,
'id_parent' => 2
),
4 => array
(
'ID' => 4,
'subcategories' => 0,
'wallpapers' => 7,
'id_parent' => 2
),
5 => array
(
'ID' => 5,
'subcategories' => 0,
'wallpapers' => 1,
'id_parent' => 2
),
6 => array
(
'ID' => 6,
'subcategories' => 0,
'wallpapers' => 3,
'id_parent' => 0
),
7 => array
(
'ID' => 7,
'subcategories' => 0,
'wallpapers' => 2,
'id_parent' => 0
),
8 => array
(
'ID' => 8,
'subcategories' => 0,
'wallpapers' => 5,
'id_parent' => 0
),
9 => array
(
'ID' => 9,
'subcategories' => 0,
'wallpapers' => 8,
'id_parent' => 0
),
10 => array
(
'ID' => 10,
'subcategories' => 0,
'wallpapers' => 5,
'id_parent' => 0
),
11 => array
(
'ID' => 11,
'subcategories' => 0,
'wallpapers' => 1,
'id_parent' => 0
),
12 => array
(
'ID' => 12,
'subcategories' => 0,
'wallpapers' => 2,
'id_parent' => 0
),
13 => array
(
'ID' => 13,
'subcategories' => 0,
'wallpapers' => 5,
'id_parent' => 0
),
14 => array
(
'ID' => 14,
'subcategories' => 0,
'wallpapers' => 0,
'id_parent' => 0
),
15 => array
(
'ID' => 15,
'subcategories' => 0,
'wallpapers' => 1,
'id_parent' => 0
),
16 => array
(
'ID' => 16,
'subcategories' => 0,
'wallpapers' => 1,
'id_parent' => 3
)

);

function parse_tree ( \$items, \$parent = 0 )
{
\$nodes = array ();

foreach ( \$items as \$id => \$attributes )
{
if ( \$attributes [ 'id_parent' ] == \$parent )
{
\$nodes [ \$id ] = \$attributes;
\$nodes [ \$id ] [ 'children' ] = parse_tree ( \$items, \$id );
}
}

return \$nodes;
}

printr ( parse_tree ( \$categories ) );

?>

derzok
05-21-2008, 04:04 PM
If you're doing what I think you're doing (that is, making a tree from an array and indicating the parent node with 'id_parent') you could make a get_parent function that'd take the node's position in the list and traverse up the tree (recursively if you like) until it finds a node that doesn't have a parent (or the stop node).

Then you'd have a loop that went through \$categories - if the parent id is 0 (it has no parent) add it to a totals array. Any other nodes that DO have a parent ID, you'll resolve the parent id with the function you wrote and add its categories and wallpapers to the parent's total in the totals array.

Kind of messy if you ask me - this is why I would write a tree class instead.

dumpfi
05-24-2008, 09:33 AM
A possible implementation:

function printr ( \$data )
{
echo '<pre>' . print_r ( \$data, TRUE ) . '</pre>';
}

\$categories = [SNIPPED]

function buildCatTree(&\$cats)
{
\$root = array();

for(\$i = 0, \$c = count(\$cats); \$i < \$c; ++\$i)
{
\$cat =& \$cats[\$i];

if(\$cat['id_parent'])
{
\$cats[\$cat['id_parent']]['children'][] =& \$cat;
}
else
{
\$root[\$cat['ID']] =& \$cat;
}
}

return \$root;
}
{
foreach(\$rootCats as \$rCat)
{
}
}
{
if(isset(\$cat['children']))
{
foreach(\$cat['children'] as \$c)
{
}
}
if(\$cat['id_parent'])
{
\$p =& \$cats[\$cat['id_parent']];
\$p['subcategories'] += \$cat['subcategories'] + 1;
\$p['wallpapers'] += \$cat['wallpapers'];
}
}

printr(buildCatTree(\$categories));dumpfi