php - 如何从3维数组中求和一个值

I have data as below :

Array
(
    [1] => Array
        (
            [A] => Array
                (
                    [AA] => 3
                    [AB] => 5
                )

            [B] => Array
                (
                    [BA] => 2
                )

    [2] => Array
        (
            [C] => Array
                (
                    [CA] => 4
                )

            [D] => Array
                (
                    [DA] => 1
                    [DB] => 2
                )
        )

    [3] => Array
        (
            [E] => Array
                (
                    [EA] => 1
                    [EB] => 2
                    [EC] => 3
                )

            [F] => Array
                (
                    [FA] => 0
                    [FB] => 7
                    [FC] => 7
                )
)

I want to sum the value and this is my expectation :

Array(
    [1] => 10        
    [2] => 7
    [3] => 20
)

Here is my code that I used for summing the value :

$total[$country_id][$province_id][$city_id] = $amount;

$result = array();
foreach( $total as $key => $val ){
         $total[$key] = array_sum ( $val );
}

can someone explain what is wrong with my code or explain how foreach work? because the result of my code is 0 and actually I just studied around 1 week about foreach. Thanks

As you want to know more about foreach, here is a more verbose solution using it :

$total = 0;
$totalByCountry = [];

// iterate over each country
foreach ($arr as $countryId => $provinces) {

    $totalByCountry[$countryId] = 0;

    // iterate over each province
    foreach ($provinces as $provinceId => $cities) {

        // iterate over each city
        foreach ($cities as $cityId => $value) {
            $totalByCountry[$countryId] += $value;
            $total += $value;
        }
    }
}

Result of var_dump(totalByCountry) :

array (size=3)
    1 => int 10
    2 => int 7
    3 => int 20

Result of var_dump($total) :

int 37

-- edit --

In real world project, you better be less verbose and use php functions made for this kind of situation like array_walk_recursive(), as in Philipp Maurer and Firoz Ahmad answers.

print the $total,When coming to the foreach, $val is an array. so when calling array_sum function, it sums the first array and assign the total to a new array's first element. That is how this is working. The reason why you code is not working, there should be a foreach outside the foreach that you have been provided. Remove this foreach from above foreach's scope.

<?php

$x=[0=>[1,2,3],1=>[2,3,4]];

$result = array();
foreach( $x as $key => $val ){
       $total[$key] = array_sum ( $val );
}
var_dump($total);
?>

If your array is 3 dimentional Code is like this,

$y=[0=>[0=>[1,2,3],1=>[3,4,5]],1=>[0=>[5,6,7],1=>[8,9,10]]];

$result = array();
foreach( $y as $vals ){
   foreach( $vals as $key => $val ){
        $total[$key] = array_sum ( $val );
   }
}
var_dump($total);

The problem with your foreach is, that your array is three layers deep, while your foreach only traverses the first and array_sum() only calculates the second layer.

An example of your foreach:

$total = [
    0 => [
        'A' => [
            'AA' => 1,
            'AB' => 2
        ],
        'B' => [
            'BA' => 3,
            'BB' => 4
        ]
    ]
];

foreach( $total as $key => $val ){
    $total[$key] = array_sum ( $val );
}

The foreach will iterate over the $total array. This is the iteraton for the example:

  1. $key = 0; $value = ['A'=>['AA'=>1,'AB'=>2], 'B'=>['BA'=>3,'BB'=>4]]
    In your loop, you then call array_sum() on $value. array_sum() adds the children of the provided array together, if they are numeric. Sadly $value is a two dimensional array and its children are arrays, so they are not numeric. That is why 0 is returned for it.

A solution to your problem would be to use the array_walk_recursive() function, that traverses inner arrays and calls a function upon them, that you can specify:

$sum = 0;
array_walk_recursive($total, function($value) use (&$sum) {
    $sum += $value;
});

The specified function adds the value of each leaf in your array to the specified variable $sum, that is given by reference to the function.

To achieve your desired output, you at first should iterate over your array and check if there exists any sub array then, again traverse all array members by using array_walk_recursive() function

<?php

    $arr = [
        [
            'A' => [
                'AA' => 3,
                'BB' => 5,
                'CC' => [
                    'DD' => 4,
                    'EE' => 5
                ]
            ],
            'B' => [
                'BA' => 2
            ]
        ],
        [
            'C' => [
                'CC' => 3,
                'CCC' => 2,
            ],
            'D' => [
                'DD' => 2
            ]
        ],

        5,
        [
            2,
            7
        ]

    ];

    $arrSum = [];

    $count = count($arr);

    for ($i = 0; $i < $count; $i++) {
        $sum = 0;
        if(is_array($arr[$i])) {
            array_walk_recursive($arr[$i], function ($item, $key) use (&$sum) {
                $sum += $item;
            });
        }
        else {
            $sum += $arr[$i];
        }

        $arrSum [] = $sum;
        $sum = 0;
    }

    var_dump($arrSum);