对 PHP 中两个关联多维数组的值求和


Sum the values of two associative multi-dimensional arrays in PHP

我正在尝试对两个关联数组的值求和。 这是第一个数组:

Array
(
[Jan 01, 2013] => Array
    (
        [COM] => 100
        [RES] => 200
    )
[Oct 28, 2014] => Array
    (
        [COM] => 300
        [RES] => 400
    )
)

这是第二个数组:

Array
(
[Jan 01, 2013] => Array
    (
        [COM] => 10
        [RES] => 20
    )
[Oct 28, 2014] => Array
    (
        [COM] => 30
        [RES] => 40
    )
)

我需要对这两个数组的值求和,以便产生以下结果:

    Array
(
[Jan 01, 2013] => Array
    (
        [COM] => 110
        [RES] => 220
    )
[Oct 28, 2014] => Array
    (
        [COM] => 330
        [RES] => 440
    )
)

我发现本教程对关联数组的值求和,但它似乎不适用于我的多维数组。 有什么建议如何做到这一点吗? 谢谢。

对第一个数组使用 foreach() 并检查第一个数组的键,无论它是否存在于第二个数组中。如果存在,则计算总和。例:

$arr1 = Array
(
    "Jan 01, 2013" => Array
    (
        "COM" => 100,
        "RES" => 200,
    ),
    "Oct 28, 2014" => Array
    (
        "COM" => 300,
        "RES" => 400,
    )
);
$arr2 = Array
(
    "Jan 01, 2013" => Array
    (
        "COM" => 10,
        "RES" => 20,
    ),
    "Oct 28, 2014" => Array
    (
        "COM" => 30,
        "RES" => 40,
   )
);
$arr3 = array();
foreach($arr1 as $key => $val):
    if(array_key_exists($key, $arr2)):
        $arr3[$key]["COM"] = $val["COM"] + $arr2[$key]["COM"];
        $arr3[$key]["RES"] = $val["RES"] + $arr2[$key]["RES"];
    endif;
endforeach;
print '<pre>';
print_r($arr3);
print '</pre>';

输出:

Array
(
    [Jan 01, 2013] => Array
        (
            [COM] => 110
            [RES] => 220
        )
    [Oct 28, 2014] => Array
        (
            [COM] => 330
            [RES] => 440
        )
)

试试这个:

<?php
   $array_01 = array(
      'a' => 1,
      'b' => 2
   );
    $array_02 = array(
      'a' => 0,
      'b' => 1,
      'c' => 2
    );
    /** first we should get the array keys union
     * this is too long...,so you can make it better :D
     * you can make this more readable
     */
    $keyUnion = array_unique(array_merge(array_keys($array_01), array_keys($array_02))); 
    $res = array();
    //sum
    foreach ($keyUnion as $k => $v) {
        $res[$v] = (isset($array_01[$v]) ? $array_01[$v] : 0) + (isset($array_02[$v]) ? $array_02[$v] : 0);
    }
    print_r($res);
?>

注意:代码只获取一维关联和

最直接/简单地说,迭代第二个数组的级别,并确定是应该将值附加到第一个数组中,还是合并求和到第一个数组中。

代码:(演示)

$arr1 = [
    "Jan 01, 2013" => ["COM" => 100, "RES" => 200, "FOO" => 5],
    "Oct 28, 2014" => ["COM" => 300, "RES" => 400]
];
$arr2 = [
    "Jan 01, 2013" => ["COM" => 10, "RES" => 20],
    "Oct 28, 2014" => ["COM" => 30, "RES" => 40]
];
foreach ($arr2 as $date => $set) {
    foreach ($set as $key => $val) {
        if (!isset($arr1[$date][$key])) {            // val is unique to 1st array, set it
            $arr1[$date][$key] = $val;
        } else {                // val already exists in 1st array, add 2nd val to 1st val
            $arr1[$date][$key] += $val;
        }
    }
}
var_export($arr1);
<小时 />

由于您不知道传入数据的子数组键,并且您有关联键,因此您可以使用 array_merge_recursive() 以非常简单求和的方式合并两个数组。

根据关联值进行合并后,可以循环新的多维数组。 在迭代时,将子数组和子数组的值表示为"可通过引用修改"——这意味着 foreach 循环将处理实际数组而不是数组的副本。 实际上,这将使更改影响新阵列并通过$assoc_merged提供所需的结果。

代码:(演示)

$arr1 = [
    "Jan 01, 2013" => ["COM" => 100, "RES" => 200, "FOO" => 5],
    "Oct 28, 2014" => ["COM" => 300, "RES" => 400]
];
$arr2 = [
    "Jan 01, 2013" => ["COM" => 10, "RES" => 20],
    "Oct 28, 2014" => ["COM" => 30, "RES" => 40]
];
$assoc_merged =array_merge_recursive($arr1, $arr2);
// var_export($assoc_merged);  // see what this makes
foreach ($assoc_merged as $date => &$set) {
    foreach ($set as $key => &$val) {
        $val = array_sum((array)$val);
        // (array) forces a lone value to be an array containing one element; avoids generating Warnings
    }
}
var_export($assoc_merged);

或其功能样式版本:(演示)

var_export(
    array_map(
        fn($set) => array_map(
            fn($v) => array_sum((array) $v),
            $set
        ),
        array_merge_recursive($arr1, $arr2)
    )
);
<小时 />

所有方法都产生相同的输出:

array (
  'Jan 01, 2013' => 
  array (
    'COM' => 110,
    'RES' => 220,
    'FOO' => 5,
  ),
  'Oct 28, 2014' => 
  array (
    'COM' => 330,
    'RES' => 440,
  ),
)