You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用多维数组实现Excel SUBTOTAL函数功能及分组求和

实现多维数组分组求和(类似Excel SUBTOTAL功能)

嘿,我来帮你搞定这个需求!要实现类似Excel SUBTOTAL的分组统计功能,针对你的$products多维数组按Id分组计算求和值,咱们用PHP就能轻松实现,下面一步步来:

基础版:按Id分组求和Quantity和Price

首先,先把你的$products数组补全(假设剩下的项是合理的测试数据):

$products = array(
    array("Id" => "000001", "Name" => "Cheese", "Quantity" => "10", "Price" => "10"),
    array("Id" => "000001", "Name" => "Cheese", "Quantity" => "20", "Price" => "20"),
    array("Id" => "000001", "Name" => "Cheese", "Quantity" => "10", "Price" => "30"),
    array("Id" => "000002", "Name" => "Ham", "Quantity" => "20", "Price" => "200"),
    array("Id" => "000002", "Name" => "Ham", "Quantity" => "15", "Price" => "180"),
    array("Id" => "000003", "Name" => "Bread", "Quantity" => "50", "Price" => "5")
);

然后是核心的分组求和代码:

// 初始化空数组存储分组结果
$groupedSummary = [];

foreach ($products as $item) {
    $productId = $item["Id"];
    // 关键:把字符串类型的数值转成数字,避免字符串拼接错误
    $quantity = (int)$item["Quantity"];
    $price = (float)$item["Price"];

    // 如果当前Id还没在结果数组里,先初始化基础信息
    if (!isset($groupedSummary[$productId])) {
        $groupedSummary[$productId] = [
            "Id" => $productId,
            "Name" => $item["Name"],
            "TotalQuantity" => 0,
            "TotalPrice" => 0.0
        ];
    }

    // 累加数量和价格
    $groupedSummary[$productId]["TotalQuantity"] += $quantity;
    $groupedSummary[$productId]["TotalPrice"] += $price;
}

// 转成和原数组一致的索引数组格式(可选)
$finalResult = array_values($groupedSummary);

// 输出结果看看
print_r($finalResult);

这段代码的逻辑很直观:

  • 遍历每个产品项,提取关键字段并转成正确的数字类型(这一步很重要,不然字符串相加会变成拼接)
  • 对每个Id做判断,第一次出现时初始化汇总项
  • 不断累加相同Id的Quantity和Price值
  • 最后用array_values()把关联数组转成索引数组,和原数组格式统一

进阶版:封装成类似SUBTOTAL的通用函数

如果你需要像Excel SUBTOTAL那样支持多种统计方式(比如计数、平均值、最大值、最小值),可以封装一个通用函数,这样复用性更强:

function groupSubtotal($sourceArray, $groupField, $calcFields, $function = 'sum') {
    $result = [];

    foreach ($sourceArray as $item) {
        $groupKey = $item[$groupField];
        // 初始化分组项,保留原字段
        if (!isset($result[$groupKey])) {
            $result[$groupKey] = $item;
            // 给每个要统计的字段初始化对应类型的初始值
            foreach ($calcFields as $field) {
                $totalKey = "Total" . ucfirst($field);
                switch ($function) {
                    case 'sum':
                    case 'count':
                        $result[$groupKey][$totalKey] = 0;
                        break;
                    case 'avg':
                        $result[$groupKey][$totalKey] = [];
                        break;
                    case 'max':
                    case 'min':
                        $result[$groupKey][$totalKey] = null;
                        break;
                }
            }
        }

        // 根据选择的统计方式处理每个字段
        foreach ($calcFields as $field) {
            $totalKey = "Total" . ucfirst($field);
            $value = is_numeric($item[$field]) ? (float)$item[$field] : 0;

            switch ($function) {
                case 'sum':
                    $result[$groupKey][$totalKey] += $value;
                    break;
                case 'count':
                    $result[$groupKey][$totalKey]++;
                    break;
                case 'avg':
                    $result[$groupKey][$totalKey][] = $value;
                    break;
                case 'max':
                    if ($result[$groupKey][$totalKey] === null || $value > $result[$groupKey][$totalKey]) {
                        $result[$groupKey][$totalKey] = $value;
                    }
                    break;
                case 'min':
                    if ($result[$groupKey][$totalKey] === null || $value < $result[$groupKey][$totalKey]) {
                        $result[$groupKey][$totalKey] = $value;
                    }
                    break;
            }
        }
    }

    // 如果是平均值统计,最后计算平均值
    if ($function === 'avg') {
        foreach ($result as &$groupItem) {
            foreach ($calcFields as $field) {
                $totalKey = "Total" . ucfirst($field);
                $values = $groupItem[$totalKey];
                $groupItem[$totalKey] = count($values) > 0 ? array_sum($values) / count($values) : 0;
            }
        }
    }

    // 转成索引数组返回
    return array_values($result);
}

// 调用示例:按Id分组,求Quantity和Price的总和
$sumResult = groupSubtotal($products, "Id", ["Quantity", "Price"], 'sum');
print_r($sumResult);

// 调用示例:按Id分组,求Price的平均值
$avgResult = groupSubtotal($products, "Id", ["Price"], 'avg');
print_r($avgResult);

这个函数可以灵活支持多种统计场景,完全对标Excel SUBTOTAL的不同功能选项,你可以根据需求选择对应的统计方式。

内容的提问来源于stack exchange,提问作者Carmen B.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:21:27