3

I am building an MLM software in PHP, one of its function is to count the downline performance. It creates an array from parent-child relationships, which can be seen below. How can I get the performance (array key: points) of my children, and their grandchildren as well through the fifth down level?

    Array
(
    [children] => Array
        (
            [0] => Array
                (
                    [id] => 1
                    [name] => Medvedev
                    [email] => 
                    [points] => 7
                    [children] => Array
                        (
                            [0] => Array
                                (
                                    [id] => 3
                                    [name] => Putin
                                    [email] => 
                                    [points] => 4
                                    [children] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [id] => 5
                                                    [name] => Nathan
                                                    [email] => 
                                                    [points] => 3
                                                )

                                            [1] => Array
                                                (
                                                    [id] => 7
                                                    [name] => George
                                                    [email] => 
                                                    [points] => 666
                                                )

                                        )

                                )

                            [1] => Array
                                (
                                    [id] => 4
                                    [name] => Lucas
                                    [email] => 
                                    [points] => 43
                                )

                        )

                )
        )

    [id] => 27
    [name] => Boss
    [email] => 
    [points] => 99999
)

2 Answers 2

3

this should work with unlimited depth starting from a main array like

$array = array(
    'children' => array( /* ADD HERE INFINITE COMBINATION OF CHILDREN ARRAY */ ),
    'id' => #,
    'name' => '',
    'email' => '',
    'points' => #
);

function recursive_children_points($arr) {
    global $hold_points;
    if (isset($arr['points'])) {
        $hold_points[] = $arr['points'];
    }
    if (isset($arr['children'])) {
        foreach ($arr['children'] as $children => $child) {
            recursive_children_points($child);
        }
    }
    return $hold_points;
}

$points = recursive_children_points($array);
print "<pre>";
print_r($points);
/**
     // OUTPUT
     Array
(
    [0] => 99999
    [1] => 7
    [2] => 4
    [3] => 3
    [4] => 666
    [5] => 43
)
**/
    print "<pre>";
Sign up to request clarification or add additional context in comments.

Comments

1

In my opinion this calls for recursion because you'll do the same thing over each flat level of the array: add the points.

so you'll need to

  • loop over each array
  • add points found
  • if we find any children, do it again but with children array

while keeping track of levels and jumping out if you reach your limit

With that in mind I thought of the following solution:

<?php

$values = array();

//first
$values[] = array('name'=>'andrej','points'=>1,'children'=>array());
$values[] = array('name'=>'peter','points'=>2,'children'=>array());
$values[] = array('name'=>'mark','points'=>3,'children'=>array());

//second
$values[0]['children'][] = array('name'=>'Sarah','points'=>4,'children'=>array());
$values[2]['children'][] = array('name'=>'Mike','points'=>5,'children'=>array());

//third 
$values[0]['children'][0]['children'][] = array('name'=>'Ron','points'=>6,'children'=>array());

//fourth
$values[0]['children'][0]['children'][0]['children'][] = array('name'=>'Ronny','points'=>7,'children'=>array());

//fifth
$values[0]['children'][0]['children'][0]['children'][0]['children'][] = array('name'=>'Marina','points'=>10,'children'=>array());

//sixth
$values[0]['children'][0]['children'][0]['children'][0]['children'][0]['children'][] = array('name'=>'Pjotr','points'=>400,'children'=>array());


function collect_elements($base, $maxLevel,$child='children',$gather='points', &$catch = array(), $level = 0) {
/*    I pass $catch by reference so that all recursive calls add to the same array
      obviously you could use it straight away but I return the created array as well
  because I find it to be cleaner in PHP (by reference is rare and can lead to confusion)

  $base = array it works on
  $maxLevel = how deep the recursion goes

  $child = key of the element where you hold your possible childnodes
      $gather = key of the element that has to be collected
*/

  $level++;
  if($level > $maxLevel) return; // we're too deep, bail out

  foreach ($base as $key => $elem) {
    // collect the element if available
    if(isset($elem[$gather])) $catch[] = $elem[$gather];

    /*
    does this element's container have children? 
       [$child] needs to be set, [$child] needs to be an array, [$child] needs to have elements itself
    */
    if (isset($elem[$child]) && is_array($elem[$child]) && count($elem[$child])){
       // if we can find another array 1 level down, recurse that as well  
       collect_elements($elem[$child],$maxLevel,$child,$gather, $catch,$level); 
    }
  }
return $catch;
}

print array_sum(collect_elements($values,5)) . PHP_EOL;

collect_elements will collect the element you're interested in (until maximum depth is reached) and append it to a flat array, so that you can act on it upon return. In this case we do an array_sum to get the total of poins collected

Only the first for parameters are interesting:

collect_elements($base, $maxLevel,$child='children',$gather='points'

not optional: $base is the array to work on $maxLevel is the maximum depth the function needs to descend into the arrays optional: $child defines the key of the element that contains the children of current element (array) $gather defines the key of the element that contains what we want to gather

The remaining parameters are just ones used for recursion

1 Comment

What happens if you don't know the maximum level?

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.