返回

PHP二维数组按列分组求和:两种高效方法详解

php

二维数组按列分组并求和

处理二维数组数据时,经常需要按某一列的值进行分组,并对组内其他列的数据进行聚合操作,例如求和。 这个问题在数据分析、报表生成等场景中很常见。本文将介绍几种解决这个问题的方法,并提供代码示例和操作步骤。

方法一:使用关联数组

这种方法的核心是利用关联数组的键来表示分组依据,值则存储每个分组的聚合结果。 代码简洁易懂,适合处理数据量不太大的情况。

PHP 代码示例:

<?php

$newData = [
    ['company_name' => 'CO 1', 'year_and_filing_date' => '2019', 'total_revenue' => '200', 'net_income' => '300', 'net_cash_ending_balance' => '150', 'long-term_debt' => '210'],
    ['company_name' => 'CO 1', 'year_and_filing_date' => '2020', 'total_revenue' => '200', 'net_income' => '300', 'net_cash_ending_balance' => '150', 'long-term_debt' => '210'],
    ['company_name' => 'CO 1', 'year_and_filing_date' => '2020', 'total_revenue' => '100', 'net_income' => '200', 'net_cash_ending_balance' => '50', 'long-term_debt' => '110']
];

$groupedData = [];

foreach ($newData as $row) {
    $year = $row['year_and_filing_date'];
    if (!isset($groupedData[$year])) {
        $groupedData[$year] = $row;  // 初始化分组数据,注意保留非求和字段
    } else {
        $groupedData[$year]['total_revenue'] += $row['total_revenue'];
        $groupedData[$year]['net_income'] += $row['net_income'];
        $groupedData[$year]['net_cash_ending_balance'] += $row['net_cash_ending_balance'];
        $groupedData[$year]['long-term_debt'] += $row['long-term_debt'];
       // 保留公司名称,这里可以根据你的实际需求进行修改,比如拼接公司名称
        $groupedData[$year]['company_name'] .=  ', ' . $row['company_name'];
    }
}

// 将结果转换为列表形式,如果需要
$result = array_values($groupedData);
print_r($result);

?>

操作步骤:

  1. 创建一个空关联数组 $groupedData 用于存储结果。
  2. 遍历原始数组 $newData
  3. year_and_filing_date 作为键,如果键不存在,则将当前行作为初始值存入 $groupedData
  4. 如果键已存在,则将需要求和的列的值累加到 $groupedData 中对应键的值上。
  5. 最后,$groupedData 中的每个键值对就代表一个分组及其聚合结果。

方法二:使用 array_reduce

array_reduce 函数提供了一种更函数式的方式来处理数组。它可以将数组迭代 reduce 成一个单一的值。

PHP 代码示例:

<?php

$newData = [ /* ... (data as before) ... */ ];

$groupedData = array_reduce($newData, function ($carry, $item) {
    $year = $item['year_and_filing_date'];
    if (!isset($carry[$year])) {
        $carry[$year] = $item;
    } else {
        $carry[$year]['total_revenue'] += $item['total_revenue'];
        $carry[$year]['net_income'] += $item['net_income'];
        $carry[$year]['net_cash_ending_balance'] += $item['net_cash_ending_balance'];
        $carry[$year]['long-term_debt'] += $item['long-term_debt'];
        $carry[$year]['company_name'] .=  ', ' . $item['company_name'];

    }
    return $carry;
}, []);


$result = array_values($groupedData);
print_r($result);

?>

操作步骤:

  1. 使用 array_reduce 函数。第一个参数是待处理的数组,第二个参数是一个回调函数,第三个参数是初始值(一个空数组)。
  2. 回调函数接收两个参数:$carry 是累积器,$item 是当前迭代的数组元素。
  3. 在回调函数中,逻辑与方法一类似,根据 year_and_filing_date 进行分组和求和。
  4. array_reduce 会将回调函数的返回值作为下一次迭代的 $carry 值。
  5. 最终,array_reduce 返回最终的 $carry 值,即分组聚合后的结果。

安全建议:

  • 对输入数据进行校验,确保数据的类型和格式符合预期,避免潜在的错误。
  • 如果涉及到数据库操作,使用参数化查询或预处理语句,防止 SQL 注入攻击。

选择哪种方法取决于个人偏好和具体场景。关联数组方法更直观易懂,array_reduce 方法则更简洁,更符合函数式编程的思想。 理解了这些方法的原理,就可以灵活地应用于实际项目中,提高数据处理的效率。