1

我需要一种方法来合并几个数组(可能大约 8 个)并对任何重复的键或子键求和。

例如:

$arr1 = [
    "Friday" => ["Breakfast" => 32, "Lunch" => 45],
    "Sunday" => ["Lunch" => 12]
];

$arr2 = [
    "Sunday" => ["Breakfast" => 7, "Lunch" => 3],
    "Monday" => ["Breakfast" => 12]
];

$arr3 = [
    "Monday" => ["Breakfast" => 31]
];

输出应该是这样的:

array (
  'Friday' => 
  array (
    'Breakfast' => 32,
    'Lunch' => 45,
  ),
  'Sunday' => 
  array (
    'Lunch' => 15,
    'Breakfast' => 7,
  ),
  'Monday' => 
  array (
    'Breakfast' => 43,
  ),
);

我怎么能把这个结合起来?我试过使用array_map().

但是对于像这样的多维数组,这似乎失败了。也尝试过使用foreach(),但这变得非常复杂。

这是我的尝试:

$total = array_map( function( $arr1, $arr2, $arr3 ){
    return( $arr1 + $arr2 + $arr3 );
}, $arr1, $arr2, $arr3 );
4

2 回答 2

1

试试这个解决方案。您可以添加任意数量的数组。但保留名称为 $arr1-$maxArraysCount

$arr1 = array(
    "Friday" => array(
        "Breakfast" => 32,
        "Lunch" => 45
    ),
    "Sunday" => array(
        "Lunch" => 12
    )
);

$arr2 = array(
    "Sunday" => array(
        "Breakfast" => 7,
        "Lunch" => 3
    ),
    "Monday" => array(
        "Breakfast" => 12
    )
);

$arr3 = array(
    "Monday" => array(
        "Breakfast" => 31
    )
);


$maxArraysCount = 8;
$return = array();
for($i = 1; $i < $maxArraysCount; $i++){
    $arr = 'arr' . $i;
    if(isset($$arr) && is_array($$arr)){
        foreach ($$arr as $day => $value) {
            foreach ($value as $eat => $count) {
                if(!isset($return[$day][$eat])) $return[$day][$eat] = 0;
                $return[$day][$eat] = $count + $return[$day][$eat];
            }
        }
    }
}

echo "<pre>";print_r($return);

这是输出:

Array
(
    [Friday] => Array
        (
            [Breakfast] => 32
            [Lunch] => 45
        )

    [Sunday] => Array
        (
            [Lunch] => 15
            [Breakfast] => 7
        )

    [Monday] => Array
        (
            [Breakfast] => 43
        )

)
于 2014-12-22T18:52:15.947 回答
0

因为您的数据结构是完全关联的,所以array_merge_recursive()将保持您的数据完整性。数组合并后,您只需要迭代日餐,将单个值转换为数组类型(如果还没有数组,则将它们转换为单元素数组),然后无条件地 all array_sum()

代码:(演示

$arr1 = [
    "Friday" => ["Breakfast" => 32, "Lunch" => 45],
    "Sunday" => ["Lunch" => 12]
];

$arr2 = [
    "Sunday" => ["Breakfast" => 7, "Lunch" => 3],
    "Monday" => ["Breakfast" => 12]
];

$arr3 = [
    "Monday" => ["Breakfast" => 31]
];

$result = [];
foreach (array_merge_recursive($arr1, $arr2, $arr3) as $day => $meals) {
    foreach ($meals as $meal => $counts) {
        $result[$day][$meal] = array_sum((array)$counts);
    }
}    
var_export($result);

输出:

array (
  'Friday' => 
  array (
    'Breakfast' => 32,
    'Lunch' => 45,
  ),
  'Sunday' => 
  array (
    'Lunch' => 15,
    'Breakfast' => 7,
  ),
  'Monday' => 
  array (
    'Breakfast' => 43,
  ),
)

为避免 Oleg 的答案中出现变量,您可以将每个输入数组填充到一个数组中,然后将它们合并(以保留重复的日期名称)。

代码:(演示

$result = [];
foreach (array_merge([$arr1], [$arr2], [$arr3]) as $array) {
    foreach ($array as $day => $meals) {
        foreach ($meals as $meal => $count) {
            $result[$day][$meal] = ($result[$day][$meal] ?? 0) + $count;
        }
    }
}

或更有效地,使用您的第一个数组预填充结果数组。

$result = $arr1;
foreach (array_merge([$arr2], [$arr3]) as $array) {
    foreach ($array as $day => $meals) {
        foreach ($meals as $meal => $count) {
            $result[$day][$meal] = ($result[$day][$meal] ?? 0) + $count;
        }
    }
}
于 2020-12-15T02:18:29.747 回答