Tuesday 4 September 2018

PHP Sum values ​​of the multidimensional array

I have following function to sum multidimensional array values.

// summing values of multidimensional array
function getSum($array, $path = array()){
    // process second argument:
    foreach ($path as $key) {
        if (!is_array($array) || !isset($array[$key])) {
            return 0; // key does not exist, return 0
        }
        $array = $array[$key];
    }
    if(is_array($array)) {
        $iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
        $sum = 0;
        foreach ($iterator as $key => $value) {
            $sum += $value;
        }
    } else{
        $sum = $array;
    }
    return $sum;
}

I'm using the function like this:
$array = array();
$array['one']['green'][20] = 20;
$array['one']['blue'][20] = 5;
$array['one']['blue'][30] = 10;

getSum($array,['one','green']); // 20
getSum($array,['one','blue',20]); // 5

Now I have a problem if I don't want to for example set any spesific color because I want that script sums all values from category 20 from all colours.
So it should be working like this:
getSum($array,['one','*',20]); // 25

Thanks for your help!
Here is example of my array:
Array (
    [1] => Array (
        [AREA I] => Array (
            [20] => 1
            [25] => 0
            [30] => 0 )
        [AREA II] => Array (
            [20] => 0
            [30] => 0 )
        [AREA III] => Array (
            [20] => 2
            [30] => 0 )
        [AREA IV] => Array (
            [20] => 0
            [30] => 3 )
        [AREA V] => Array (
            [20] => 4
            [25] => 0
            [30] => 3 )
    )
    [2] => Array (
        [AREA I] => Array (
            [20] => 0
            [30] => 0 )
        [AREA II] => Array (
            [20] => 0
            [30] => 0 )
    )
)

And here is example of my getSum call:
getSum($visitsandinfosact,['*','*',20]); // should print 7


Recursive Function

I was not sure if ['one','*'] should give 45 but if it should just return 0 you just have to remove the else if (empty($filterList) && is_array($value) && $first == "*")condition. All values which are not arrays are just converted to int via intval and added to the sum. If you wanna use float then use floatval instead of intval
function getSum($array, $filterList = array('*')) {
    $sum = 0;
    $first = array_shift($filterList);
    foreach ($array as $key => $value) {
        if ($key == $first || $first == "*") {
            if (is_array($value) && !empty($filterList)) {
                $sum += getSum($value, $filterList);
            } else if (empty($filterList) && is_array($value)) {
                $sum += getSum($value, array("*"));
            } else if (empty($filterList)) {
                $sum += intval($value);
            }
        }
    }
    return $sum;
}

echo getSum($array,['one','*',20], 10) . "\n"; // 25
echo getSum($array,['one','*','*',20]) . "\n"; // 10
echo getSum($array,['one','*']) . "\n"; // 45
echo getSum($array) . "\n"; // 45

Input Array

$array = array();
$array['one'] = array();
$array['one']['green'] = array();
$array['one']['green'][20] = 20;
$array['one']['blue'] = array();
$array['one']['blue'][20] = 5;
$array['one']['blue'][30] = 10;
$array['one']['orange']['red'][20] = 10;

Output

Only the numbers are outputted but just added the input params for better understanding.
25 // (['one','*',20])
10 // (['one','*','*',20])
45 // (['one','*'])
45 // no filterList

0 comments:

Post a Comment