根据键中的年份子字符串对关联数组中的值进行分组和求和



我正在尝试根据带有月-年("M y"(日期格式的键的数组对所有年度金额求和。

$array_list = [
"Jan 2016" => 2,
"Feb 2016" => 4,
"Mar 2016" => 2,
"Apr 2016" => 0,
"Jan 2017" => 9,
"Feb 2017" => 2,
"Mar 2017" => 5,
"Jan 2018" => 4,
"Feb 2018" => 6
];

法典:

<table border='1' cellpadding='5' cellspancing='3'>
<tr>
<td>SN</td>
<td>Month </td>
<td>Year </td>
<td>is new? </td>
<td>Data</td>
<td>Total</td>
</tr>
<?php 
$prev_year = 0; 
$i = 1;
$total_val = 0; 
foreach ($array_list as $key => $val):
$row_span = 0; 
$MonthYear_label    = explode(" ", $key); 
$year_label = $MonthYear_label[1];
$month_label = $MonthYear_label[0];
$curr_year = $year_label;
if ($curr_year == $prev_year) {
$str = "same";
$total_val = $total_val + $val; 
} else {
if ($i == 1) {
//skip for first time.. first iterator 
} else {
echo "<tr>
<td colspan='6'>&nbsp;&nbsp;</td>
</tr>";
}
$str = "--new--";
$total_val = $val;      
}
echo '<tr> 
<td>' . $i . '</td>
<td>' . $month_label . '</td>
<td>' . $year_label . ' </td>
<td>' . $str . '</td>
<td>' . $val . '</td>
<td><b>' . $total_val . '</b></td>
</tr>';
$i++; 
$prev_year = $curr_year; 
endforeach; 
?> 
</table>

电流输出:

电流输出

我期待什么?通过逐年添加这些数据。

期望的输出

注:所有数据按年份显示,数据列代表数据总和

<?php 
$array_list= array("Jan 2016"=>2, "Feb 2016"=>4, "Mar 2016"=>2,"Apr 2016"=>0, "Jan 2017"=>9,"Feb 2017"=>2,"Mar 2017"=>5,"Jan 2018"=>4,"Feb 2018"=>6);
?>
<table border='1' cellpadding='5' cellspancing='3'>
<tr>
<td>SN</td>
<td>Month/Year</td>
<td>Data</td>
</tr>
<?php 
$array = array();
foreach($array_list as $key => $value):
$MonthYear_label    = explode(" ",$key); 
$year_label         = $MonthYear_label[1];
$month_label        = $MonthYear_label[0];
$curr_year          = $year_label; 
$array[$curr_year]['count'] =  $array[$curr_year]['count'] + $value;
endforeach; 
$i = 1;
foreach ($array as $key => $value) {
echo '<tr> 
<td>'.$i.'</td>
<td>'.$key.'</td>
<td>'.$value['count'].' </td>
</td>';
}
?>
</table>

您可以使用两个 foreach 数组和一堆array_funtions来过滤数组。
我首先找到所有年份,并在第二个循环中循环唯一值。
然后,我使用 array_sum 和 array_intersect 来查找$year并对值求和。
输出数组$res应该易于在表中输出。

$array_list= array("Jan 2016"=>2, "Feb 2016"=>4, "Mar 2016"=>2,"Apr 2016"=>0, "Jan 2017"=>9,"Feb 2017"=>2,"Mar 2017"=>5,"Jan 2018"=>4,"Feb 2018"=>6); 
foreach(array_keys($array_list) as $key){
$years[] = explode(" ", $key)[1];
}
foreach(array_unique($years) as $year){
$res[$year] = array_sum(array_intersect_key(array_values($array_list), array_intersect($years, [$year])));
}
var_dump($res);

因为我发现与array_functions匹配的年份,数组不必按排序顺序排列。


https://3v4l.org/kCBRE 性能:https://3v4l.org/OgT0a

除了 HTML,您还可以选择创建一个新的年度总计数组,也可以将一维数组转换为包含月份金额和年份总计的二维数组。 这可能是一种编程风格的选择,因为这两种技术都是明智的。

  1. 创建单独的年份总计数组。 这会产生比下一个代码段更多的精简数据(没有冗余数据(,但在 HTML 标记生成的后期,您需要重新提取 year 子字符串才能访问总计数组。

    1. 循环数组的副本。
    2. 从密钥中提取年份。
    3. 申报或更新年份金额(取决于以前是否遇到过(。

    代码:(演示(

    $totals = [];
    foreach ($array as $date => $amount) {
    $year = substr($date, -4);
    $totals[$year] = ($totals[$year] ?? 0) + $amount;
    }
    
  2. 在原始数组中创建数据行以包含月金额及其年总计。这会在数组中存储冗余的总金额数据,但意味着您无需重新提取年份值即可访问年份金额。

    1. 迭代时循环并修改原始数组。
    2. 从密钥中提取年份。
    3. 用包含原始整数值 AND 引用变量的数组覆盖$amount变量的整数类型值。
    4. 通过将每个遇到的金额添加到缓存的总计来更新特定于年份的参考值。

    代码:(演示(

    foreach ($array as $date => &$amount) {
    $year = substr($date, -4);
    $amount = ['month' => $amount, 'total' => &$ref[$year]];
    $ref[$year] = ($ref[$year] ?? 0) + $amount['month'];
    }
    

最新更新