0

This is a question for all the array specialists out there. I have an multi dimension array with a result as number (can be 0,1 or 2) and need the average for each grouped by parent.

In the example below the calculation would be:

subentry1_sub1 = 2 + 2 = 4 (4/2=2)

subentry1_sub2 = 1 + 1 = 2 (2/2=1)

So what I try to archive in PHP is the following result:

subentry1_sub1 average = 2

subentry1_sub2 average = 1

...

I already tried some solutions from similar questions. But with all the recursive functions I didn't managed to get it aggregated by the last child name (e.g. subentry1_sub1).

Any ideas?

EDIT:

subentry1_sub1 is 2 + 2 because its two times in the array

[entry1] => [subentry1] => [subentry1_sub1] => result

[entry2] => [subentry1] => [subentry1_sub1] => result

Array
(
    [entry1] => Array
        (
            [subentry1] => Array
                (
                    [subentry1_sub1] => Array
                        (
                            [value] => abc
                            [result] => 2
                        )

                    [subentry1_sub2] => Array
                        (
                            [value] => abc
                            [result] => 1
                        )

                )

            [subentry2] => Array
                (
                    [subentry2_sub1] => Array
                        (
                            [value] => abc
                            [result] => 1
                        )

                    [subentry2_sub2] => Array
                        (
                            [value] => abc
                            [result] => 1
                        )

                )

        )

    [entry2] => Array
        (
            [subentry1] => Array
                (
                    [subentry1_sub1] => Array
                        (
                            [value] => abc
                            [result] => 2
                        )

                    [subentry1_sub2] => Array
                        (
                            [value] => abc
                            [result] => 1
                        )

                )

            [subentry2] => Array
                (
                    [subentry2_sub1] => Array
                        (
                            [value] => abc
                            [result] => 1
                        )

                    [subentry2_sub2] => Array
                        (
                            [value] => abc
                            [result] => 1
                        )

                )

        )        
)
2
  • why is subentry1_sub1 = 2 + 2? Commented Sep 2, 2016 at 11:34
  • Because it's two times in the array: [entry1] => [subentry1] => [subentry1_sub1] => result [entry2] => [subentry1] => [subentry1_sub1] => result Commented Sep 2, 2016 at 11:36

4 Answers 4

1

Try this code. In this i have created a new array $sum which will add result value of same subentry childs with same key and another array $count which will count the number of times each key repeats

<?php   
    $data = array('entry1'=>array(
         'subentry1'=>
             array(
               'subentry1_sub1'=>array('value'=>'abc','result'=>2),
               'subentry1_sub2'=>array('value'=>'abc','result'=>1)
             ),
         'subentry2'=>
             array(
               'subentry2_sub1'=>array('value'=>'abc','result'=>1),
               'subentry2_sub2'=>array('value'=>'abc','result'=>1)
             )

          ),
     'entry2'=>array(
         'subentry1'=>
             array(
               'subentry1_sub1'=>array('value'=>'abc','result'=>2),
               'subentry1_sub2'=>array('value'=>'abc','result'=>1)
             ),
         'subentry2'=>
             array(
               'subentry2_sub1'=>array('value'=>'abc','result'=>1),
               'subentry2_sub2'=>array('value'=>'abc','result'=>1)
             )
          )
    );

$sum = array();
$repeat = array();

    foreach($data as $input){
        foreach($input as $array){
                foreach($array as $key=>$value){
                        if(array_key_exists($key,$sum)){
                        $repeat[$key] = $repeat[$key]+1;
                        $sum[$key] = $sum[$key] + $value['result'];
                        }else{
                        $repeat[$key] = 1;
                        $sum[$key] = $value['result'];                              
                }}}}                    
echo "<pre>";
print_r($sum);
print_r($repeat);  
foreach($sum as $key=>$value){
   echo $key. ' Average = '. $value/$repeat[$key]."</br>";  
    }

Output

Array
(
    [subentry1_sub1] => 4
    [subentry1_sub2] => 2
    [subentry2_sub1] => 2
    [subentry2_sub2] => 2
)
Array
(
    [subentry1_sub1] => 2
    [subentry1_sub2] => 2
    [subentry2_sub1] => 2
    [subentry2_sub2] => 2
)


subentry1_sub1 Average = 2
subentry1_sub2 Average = 1
subentry2_sub1 Average = 1
subentry2_sub2 Average = 1

You can easily calculate avg now

Note : As you mentioned you are counting occurence of subentry1_sub1 etc so i did the same so it will also count whether key result exists or not

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

1 Comment

Thanks man! This is exactly what I searched for! It's working great.
1

I know this is an old thread but im pretty sure there is a much easier way of doing this for anyone who is interested:

If you know the result will always be a number:

foreach($my_array as $entry_name => $entry_data)
{
   foreach($entry_data as $sub_name => $sub_data) 
   {
      $sub_results = array_column($sub_data, 'result');
      $averages[$entry_name][$sub_name] = array_sum($sub_results)/count($sub_results);
   }
} 

If its possible the result could be NULL or empty, this will check it and return 'N/A' if there is no valid data to calculate an average from:

foreach($my_array as $entry_name => $entry_data)
{
   foreach($entry_data as $sub_name => $sub_data) 
   {
      $sub_results = array_filter(array_column($sub_data, 'result'));
      $averages[$entry_name][$sub_name] = (count($sub_results) > 0 ? array_sum($sub_results)/count($sub_results) : 'N/A');
   }
} 

both of these solutions will give you an averages array that will output the average per subentry per entry.

Comments

0

Try this like,

<?php
    $data=array('entry1'=>array(
         'subentry1'=>
             array(
               'subentry1_sub1'=>array('value'=>'abc','result'=>3),
               'subentry1_sub2'=>array('value'=>'abc','result'=>3)
             ),
         'subentry2'=>
             array(
               'subentry2_sub1'=>array('value'=>'abc','result'=>2),
               'subentry2_sub2'=>array('value'=>'abc','result'=>8)
             )

          ),
     'entry2'=>array(
         'subentry1'=>
             array(
               'subentry1_sub1'=>array('value'=>'abc','result'=>6),
               'subentry1_sub2'=>array('value'=>'abc','result'=>6)
             ),
         'subentry2'=>
             array(
               'subentry2_sub1'=>array('value'=>'abc','result'=>10),
               'subentry2_sub2'=>array('value'=>'abc','result'=>12)
             )
          )
    );

    foreach($data as $k=>$v){
        echo "----------------$k---------------------\n";
        if(is_array($v)){
            foreach($v as $a=>$b){
                if(is_array($b)){
                    echo $a.' average = ';
                    $c=array_keys($b);// now get *_sub*
                    $v1=isset($b[$c[0]]['result']) ? $b[$c[0]]['result'] : '';
                    $v2=isset($b[$c[1]]['result']) ? $b[$c[1]]['result'] : '';
                    echo ($v1+$v2)/2;
                    echo "\n";
                }                   
            }
        }
    }

Online Demo

1 Comment

Thanks for your answer. The example above is just an excerpt. The real data are much much bigger. So hardcoding the keys won't work.
0

In the meantime I found a simple working solution myself:

foreach ($data as $level2) {
    foreach ($level2 as $level3) {
        foreach ($level3 as $keyp => $level4) {
            foreach ($level4 as $key => $value) {
                if($key == 'result') $stats[$keyp] += $value;
            }
        }
    }
}

With that you get the total for every key in an new array $stats.

But be sure to checkout the solution from user1234, too. It's working great and already includes the calculation of the average. https://stackoverflow.com/a/39292593/2466703

Comments

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.