2

I have the following PHP array:

Array
(

    [13] => Array
        (
            [bond] => 5
            [level] => 1
            [sub] => Array
                (
                    [1] => Array
                        (
                            [bond] => 7
                            [level] => 2
                            [sub] => Array
                                (
                                    [7] => Array
                                        (
                                            [bond] => 9
                                            [level] => 3
                                            [sub] => Array
                                                (
                                                )

                                        )

                                    [18] => Array
                                        (
                                            [bond] => 6
                                            [level] => 3
                                            [sub] => Array
                                                (
                                                )

                                        )

                                    [24] => Array
                                        (
                                            [bond] => 9
                                            [level] => 3
                                            [sub] => Array
                                                (
                                                )

                                        )

                                )

                        )

                )

        )

    [14] => Array
        (
            [bond] => 4
            [level] => 1
            [sub] => Array
                (
                )

        )

    [21] => Array
        (
            [bond] => 5
            [level] => 1
            [sub] => Array
                (
                    [19] => Array
                        (
                            [bond] => 8
                            [level] => 2
                            [sub] => Array
                                (
                                )

                        )

                )

        )

)

How can I count, for each entry, the count of its sub entries, if any?

So to these keys/values should be added to the array:

[13]['count'] = 1;
[13][1]['count'] = 3;
[13][1][7]['count'] = 0;
...
[14]['count'] = 0;
... etc

I can't wrap my head around this. Is it a recursive function? Is it a while(true) loop inside a foreach loop? Do I use global variables to alter the array?

I tried everything I could come up with and I just can't do it.

EDIT:

Here's my solution for 2 levels deep. I am unable to make this recursively work for infinite levels:

   foreach($items as $cell=>$data){
      $count = count($data['sub']);
      $items[$cell]['count'] = $count;
      if ($count){
         foreach($data['sub'] as $cell2=>$data2){
            $count = count($data2['sub']);
            $items[$cell]['sub'][$cell2]['count'] = $count;
         }
      }
   }
2
  • Yes, you can probably do this by all the methods you mentioned (although I'd probably go for a recursive function). Can you post your most promising attempts in the question? Commented Feb 16, 2015 at 22:58
  • this array looks like a tree, search for 'Tree Traversing Algorithms' Commented Feb 16, 2015 at 23:04

1 Answer 1

2
  • your code is o.k, but the sentence Here's my solution for 2 levels deep. I am unable to make this recursively work for infinite levels is not o.k at all. In recursion you never process children nodes/other nodes in the current node, you can't process level 2 in level 1, the idea is to break the problem into sub problems and treat each independently as if it was standing there all alone.
  • Basically, in such a problem like yours (where the output of each level is some thing accumulated to the output of the previous level), you will need to make a function that accepts the output of the previous level as a parameter, accumulate your output in each level and then redoing it again for children

function processTree(&$parent, $items) {
   // here treat this node/level as if it were alone, there are no children
   foreach($items as $cell=>$data){
      $count = count($data['sub']);
      // so you just need to accumulate the current count to the parent array
      $parent[$cell]['count'] = $count;
      if ($count){
         // and here you process children passing them their parent array to which they will accumulate their output     
	 processTree($parent[$cell], $data['sub']);
      }
   }
}
// start the output with an empty array for level 1 nodels
$res = array();
processTree($res, $your_tree);
print_r($res);

I hope that the idea of recursion isclear, the most important thing is not getting the job done but knowing how it's done, so I'm here if you have comments

Sign up to request clarification or add additional context in comments.

2 Comments

Oh dear God you freaking saved me. Sorry for my words, but I was DESPERATELY trying to figure out how to recursively count subarray sizes to find out the largest one no matter where in the array it would be, with your code I've managed it. THANK YOU!
Glad that something this old helped you :D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.